PostgreSQL Source Code git master
Loading...
Searching...
No Matches
clauses.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/table.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/rel.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
 
struct  grouping_walker_ctx
 

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 bool grouping_conflict_walker (Node *node, grouping_walker_ctx *ctx)
 
static bool grouping_check_operands (Oid opno, Oid inputcollid, List *args, grouping_walker_ctx *ctx)
 
static bool grouping_check_operand (Node *arg, Oid opno, Oid inputcollid, grouping_walker_ctx *ctx)
 
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)
 
bool expression_has_grouping_conflict (Node *expr, grouping_eqop_callback get_eqop, void *context)
 
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 1217 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 2691 of file clauses.c.

2706{
2707
2708 /* since this function recurses, it could be driven to stack overflow */
2710
2711 if (node == NULL)
2712 return NULL;
2713 switch (nodeTag(node))
2714 {
2715 case T_Param:
2716 {
2717 Param *param = (Param *) node;
2718 ParamListInfo paramLI = context->boundParams;
2719
2720 /* Look to see if we've been given a value for this Param */
2721 if (param->paramkind == PARAM_EXTERN &&
2722 paramLI != NULL &&
2723 param->paramid > 0 &&
2724 param->paramid <= paramLI->numParams)
2725 {
2728
2729 /*
2730 * Give hook a chance in case parameter is dynamic. Tell
2731 * it that this fetch is speculative, so it should avoid
2732 * erroring out if parameter is unavailable.
2733 */
2734 if (paramLI->paramFetch != NULL)
2735 prm = paramLI->paramFetch(paramLI, param->paramid,
2736 true, &prmdata);
2737 else
2738 prm = &paramLI->params[param->paramid - 1];
2739
2740 /*
2741 * We don't just check OidIsValid, but insist that the
2742 * fetched type match the Param, just in case the hook did
2743 * something unexpected. No need to throw an error here
2744 * though; leave that for runtime.
2745 */
2746 if (OidIsValid(prm->ptype) &&
2747 prm->ptype == param->paramtype)
2748 {
2749 /* OK to substitute parameter value? */
2750 if (context->estimate ||
2751 (prm->pflags & PARAM_FLAG_CONST))
2752 {
2753 /*
2754 * Return a Const representing the param value.
2755 * Must copy pass-by-ref datatypes, since the
2756 * Param might be in a memory context
2757 * shorter-lived than our output plan should be.
2758 */
2759 int16 typLen;
2760 bool typByVal;
2761 Datum pval;
2762 Const *con;
2763
2765 &typLen, &typByVal);
2766 if (prm->isnull || typByVal)
2767 pval = prm->value;
2768 else
2769 pval = datumCopy(prm->value, typByVal, typLen);
2770 con = makeConst(param->paramtype,
2771 param->paramtypmod,
2772 param->paramcollid,
2773 (int) typLen,
2774 pval,
2775 prm->isnull,
2776 typByVal);
2777 con->location = param->location;
2778 return (Node *) con;
2779 }
2780 }
2781 }
2782
2783 /*
2784 * Not replaceable, so just copy the Param (no need to
2785 * recurse)
2786 */
2787 return (Node *) copyObject(param);
2788 }
2789 case T_WindowFunc:
2790 {
2791 WindowFunc *expr = (WindowFunc *) node;
2792 Oid funcid = expr->winfnoid;
2793 List *args;
2794 Expr *aggfilter;
2797
2798 /*
2799 * We can't really simplify a WindowFunc node, but we mustn't
2800 * just fall through to the default processing, because we
2801 * have to apply expand_function_arguments to its argument
2802 * list. That takes care of inserting default arguments and
2803 * expanding named-argument notation.
2804 */
2807 elog(ERROR, "cache lookup failed for function %u", funcid);
2808
2810 false, expr->wintype,
2811 func_tuple);
2812
2814
2815 /* Now, recursively simplify the args (which are a List) */
2816 args = (List *)
2819 context);
2820 /* ... and the filter expression, which isn't */
2821 aggfilter = (Expr *)
2823 context);
2824
2825 /* And build the replacement WindowFunc node */
2827 newexpr->winfnoid = expr->winfnoid;
2828 newexpr->wintype = expr->wintype;
2829 newexpr->wincollid = expr->wincollid;
2830 newexpr->inputcollid = expr->inputcollid;
2831 newexpr->args = args;
2832 newexpr->aggfilter = aggfilter;
2833 newexpr->runCondition = expr->runCondition;
2834 newexpr->winref = expr->winref;
2835 newexpr->winstar = expr->winstar;
2836 newexpr->winagg = expr->winagg;
2838 newexpr->location = expr->location;
2839
2840 return (Node *) newexpr;
2841 }
2842 case T_FuncExpr:
2843 {
2844 FuncExpr *expr = (FuncExpr *) node;
2845 List *args = expr->args;
2846 Expr *simple;
2848
2849 /*
2850 * Code for op/func reduction is pretty bulky, so split it out
2851 * as a separate function. Note: exprTypmod normally returns
2852 * -1 for a FuncExpr, but not when the node is recognizably a
2853 * length coercion; we want to preserve the typmod in the
2854 * eventual Const if so.
2855 */
2856 simple = simplify_function(expr->funcid,
2857 expr->funcresulttype,
2858 exprTypmod(node),
2859 expr->funccollid,
2860 expr->inputcollid,
2861 &args,
2862 expr->funcvariadic,
2863 true,
2864 true,
2865 context);
2866 if (simple) /* successfully simplified it */
2867 return (Node *) simple;
2868
2869 /*
2870 * The expression cannot be simplified any further, so build
2871 * and return a replacement FuncExpr node using the
2872 * possibly-simplified arguments. Note that we have also
2873 * converted the argument list to positional notation.
2874 */
2876 newexpr->funcid = expr->funcid;
2877 newexpr->funcresulttype = expr->funcresulttype;
2878 newexpr->funcretset = expr->funcretset;
2879 newexpr->funcvariadic = expr->funcvariadic;
2880 newexpr->funcformat = expr->funcformat;
2881 newexpr->funccollid = expr->funccollid;
2882 newexpr->inputcollid = expr->inputcollid;
2883 newexpr->args = args;
2884 newexpr->location = expr->location;
2885 return (Node *) newexpr;
2886 }
2887 case T_Aggref:
2888 node = ece_generic_processing(node);
2889 if (context->root != NULL)
2890 return simplify_aggref((Aggref *) node, context);
2891 return node;
2892 case T_OpExpr:
2893 {
2894 OpExpr *expr = (OpExpr *) node;
2895 List *args = expr->args;
2896 Expr *simple;
2897 OpExpr *newexpr;
2898
2899 /*
2900 * Need to get OID of underlying function. Okay to scribble
2901 * on input to this extent.
2902 */
2903 set_opfuncid(expr);
2904
2905 /*
2906 * Code for op/func reduction is pretty bulky, so split it out
2907 * as a separate function.
2908 */
2909 simple = simplify_function(expr->opfuncid,
2910 expr->opresulttype, -1,
2911 expr->opcollid,
2912 expr->inputcollid,
2913 &args,
2914 false,
2915 true,
2916 true,
2917 context);
2918 if (simple) /* successfully simplified it */
2919 return (Node *) simple;
2920
2921 /*
2922 * If the operator is boolean equality or inequality, we know
2923 * how to simplify cases involving one constant and one
2924 * non-constant argument.
2925 */
2926 if (expr->opno == BooleanEqualOperator ||
2928 {
2929 simple = (Expr *) simplify_boolean_equality(expr->opno,
2930 args);
2931 if (simple) /* successfully simplified it */
2932 return (Node *) simple;
2933 }
2934
2935 /*
2936 * The expression cannot be simplified any further, so build
2937 * and return a replacement OpExpr node using the
2938 * possibly-simplified arguments.
2939 */
2941 newexpr->opno = expr->opno;
2942 newexpr->opfuncid = expr->opfuncid;
2943 newexpr->opresulttype = expr->opresulttype;
2944 newexpr->opretset = expr->opretset;
2945 newexpr->opcollid = expr->opcollid;
2946 newexpr->inputcollid = expr->inputcollid;
2947 newexpr->args = args;
2948 newexpr->location = expr->location;
2949 return (Node *) newexpr;
2950 }
2951 case T_DistinctExpr:
2952 {
2953 DistinctExpr *expr = (DistinctExpr *) node;
2954 List *args;
2955 ListCell *arg;
2956 bool has_null_input = false;
2957 bool all_null_input = true;
2958 bool has_nonconst_input = false;
2959 bool has_nullable_nonconst = false;
2960 Expr *simple;
2962
2963 /*
2964 * Reduce constants in the DistinctExpr's arguments. We know
2965 * args is either NIL or a List node, so we can call
2966 * expression_tree_mutator directly rather than recursing to
2967 * self.
2968 */
2969 args = (List *) expression_tree_mutator((Node *) expr->args,
2971 context);
2972
2973 /*
2974 * We must do our own check for NULLs because DistinctExpr has
2975 * different results for NULL input than the underlying
2976 * operator does. We also check if any non-constant input is
2977 * potentially nullable.
2978 */
2979 foreach(arg, args)
2980 {
2981 if (IsA(lfirst(arg), Const))
2982 {
2985 }
2986 else
2987 {
2988 has_nonconst_input = true;
2989 all_null_input = false;
2990
2991 if (!has_nullable_nonconst &&
2992 !expr_is_nonnullable(context->root,
2993 (Expr *) lfirst(arg),
2995 has_nullable_nonconst = true;
2996 }
2997 }
2998
2999 if (!has_nonconst_input)
3000 {
3001 /*
3002 * All inputs are constants. We can optimize this out
3003 * completely.
3004 */
3005
3006 /* all nulls? then not distinct */
3007 if (all_null_input)
3008 return makeBoolConst(false, false);
3009
3010 /* one null? then distinct */
3011 if (has_null_input)
3012 return makeBoolConst(true, false);
3013
3014 /* otherwise try to evaluate the '=' operator */
3015 /* (NOT okay to try to inline it, though!) */
3016
3017 /*
3018 * Need to get OID of underlying function. Okay to
3019 * scribble on input to this extent.
3020 */
3021 set_opfuncid((OpExpr *) expr); /* rely on struct
3022 * equivalence */
3023
3024 /*
3025 * Code for op/func reduction is pretty bulky, so split it
3026 * out as a separate function.
3027 */
3028 simple = simplify_function(expr->opfuncid,
3029 expr->opresulttype, -1,
3030 expr->opcollid,
3031 expr->inputcollid,
3032 &args,
3033 false,
3034 false,
3035 false,
3036 context);
3037 if (simple) /* successfully simplified it */
3038 {
3039 /*
3040 * Since the underlying operator is "=", must negate
3041 * its result
3042 */
3043 Const *csimple = castNode(Const, simple);
3044
3045 csimple->constvalue =
3046 BoolGetDatum(!DatumGetBool(csimple->constvalue));
3047 return (Node *) csimple;
3048 }
3049 }
3050 else if (!has_nullable_nonconst)
3051 {
3052 /*
3053 * There are non-constant inputs, but since all of them
3054 * are proven non-nullable, "IS DISTINCT FROM" semantics
3055 * are much simpler.
3056 */
3057
3058 OpExpr *eqexpr;
3059
3060 /*
3061 * If one input is an explicit NULL constant, and the
3062 * other is a non-nullable expression, the result is
3063 * always TRUE.
3064 */
3065 if (has_null_input)
3066 return makeBoolConst(true, false);
3067
3068 /*
3069 * Otherwise, both inputs are known non-nullable. In this
3070 * case, "IS DISTINCT FROM" is equivalent to the standard
3071 * inequality operator (usually "<>"). We convert this to
3072 * an OpExpr, which is a more efficient representation for
3073 * the planner. It can enable the use of partial indexes
3074 * and constraint exclusion. Furthermore, if the clause
3075 * is negated (ie, "IS NOT DISTINCT FROM"), the resulting
3076 * "=" operator can allow the planner to use index scans,
3077 * merge joins, hash joins, and EC-based qual deductions.
3078 */
3080 eqexpr->opno = expr->opno;
3081 eqexpr->opfuncid = expr->opfuncid;
3082 eqexpr->opresulttype = BOOLOID;
3083 eqexpr->opretset = expr->opretset;
3084 eqexpr->opcollid = expr->opcollid;
3085 eqexpr->inputcollid = expr->inputcollid;
3086 eqexpr->args = args;
3087 eqexpr->location = expr->location;
3088
3090 context);
3091 }
3092 else if (has_null_input)
3093 {
3094 /*
3095 * One input is a nullable non-constant expression, and
3096 * the other is an explicit NULL constant. We can
3097 * transform this to a NullTest with !argisrow, which is
3098 * much more amenable to optimization.
3099 */
3100
3102
3103 nt->arg = (Expr *) (IsA(linitial(args), Const) ?
3104 lsecond(args) : linitial(args));
3105 nt->nulltesttype = IS_NOT_NULL;
3106
3107 /*
3108 * argisrow = false is correct whether or not arg is
3109 * composite
3110 */
3111 nt->argisrow = false;
3112 nt->location = expr->location;
3113
3114 return eval_const_expressions_mutator((Node *) nt, context);
3115 }
3116
3117 /*
3118 * The expression cannot be simplified any further, so build
3119 * and return a replacement DistinctExpr node using the
3120 * possibly-simplified arguments.
3121 */
3123 newexpr->opno = expr->opno;
3124 newexpr->opfuncid = expr->opfuncid;
3125 newexpr->opresulttype = expr->opresulttype;
3126 newexpr->opretset = expr->opretset;
3127 newexpr->opcollid = expr->opcollid;
3128 newexpr->inputcollid = expr->inputcollid;
3129 newexpr->args = args;
3130 newexpr->location = expr->location;
3131 return (Node *) newexpr;
3132 }
3133 case T_NullIfExpr:
3134 {
3135 NullIfExpr *expr;
3136 ListCell *arg;
3137 bool has_nonconst_input = false;
3138
3139 /* Copy the node and const-simplify its arguments */
3140 expr = (NullIfExpr *) ece_generic_processing(node);
3141
3142 /* If either argument is NULL they can't be equal */
3143 foreach(arg, expr->args)
3144 {
3145 if (!IsA(lfirst(arg), Const))
3146 has_nonconst_input = true;
3147 else if (((Const *) lfirst(arg))->constisnull)
3148 return (Node *) linitial(expr->args);
3149 }
3150
3151 /*
3152 * Need to get OID of underlying function before checking if
3153 * the function is OK to evaluate.
3154 */
3155 set_opfuncid((OpExpr *) expr);
3156
3157 if (!has_nonconst_input &&
3158 ece_function_is_safe(expr->opfuncid, context))
3159 return ece_evaluate_expr(expr);
3160
3161 return (Node *) expr;
3162 }
3164 {
3165 ScalarArrayOpExpr *saop;
3166
3167 /* Copy the node and const-simplify its arguments */
3169
3170 /* Make sure we know underlying function */
3171 set_sa_opfuncid(saop);
3172
3173 /*
3174 * If all arguments are Consts, and it's a safe function, we
3175 * can fold to a constant
3176 */
3177 if (ece_all_arguments_const(saop) &&
3178 ece_function_is_safe(saop->opfuncid, context))
3179 return ece_evaluate_expr(saop);
3180 return (Node *) saop;
3181 }
3182 case T_BoolExpr:
3183 {
3184 BoolExpr *expr = (BoolExpr *) node;
3185
3186 switch (expr->boolop)
3187 {
3188 case OR_EXPR:
3189 {
3190 List *newargs;
3191 bool haveNull = false;
3192 bool forceTrue = false;
3193
3195 context,
3196 &haveNull,
3197 &forceTrue);
3198 if (forceTrue)
3199 return makeBoolConst(true, false);
3200 if (haveNull)
3202 makeBoolConst(false, true));
3203 /* If all the inputs are FALSE, result is FALSE */
3204 if (newargs == NIL)
3205 return makeBoolConst(false, false);
3206
3207 /*
3208 * If only one nonconst-or-NULL input, it's the
3209 * result
3210 */
3211 if (list_length(newargs) == 1)
3212 return (Node *) linitial(newargs);
3213 /* Else we still need an OR node */
3214 return (Node *) make_orclause(newargs);
3215 }
3216 case AND_EXPR:
3217 {
3218 List *newargs;
3219 bool haveNull = false;
3220 bool forceFalse = false;
3221
3223 context,
3224 &haveNull,
3225 &forceFalse);
3226 if (forceFalse)
3227 return makeBoolConst(false, false);
3228 if (haveNull)
3230 makeBoolConst(false, true));
3231 /* If all the inputs are TRUE, result is TRUE */
3232 if (newargs == NIL)
3233 return makeBoolConst(true, false);
3234
3235 /*
3236 * If only one nonconst-or-NULL input, it's the
3237 * result
3238 */
3239 if (list_length(newargs) == 1)
3240 return (Node *) linitial(newargs);
3241 /* Else we still need an AND node */
3242 return (Node *) make_andclause(newargs);
3243 }
3244 case NOT_EXPR:
3245 {
3246 Node *arg;
3247
3248 Assert(list_length(expr->args) == 1);
3250 context);
3251
3252 /*
3253 * Use negate_clause() to see if we can simplify
3254 * away the NOT.
3255 */
3256 return negate_clause(arg);
3257 }
3258 default:
3259 elog(ERROR, "unrecognized boolop: %d",
3260 (int) expr->boolop);
3261 break;
3262 }
3263 break;
3264 }
3265 case T_JsonValueExpr:
3266 {
3267 JsonValueExpr *jve = (JsonValueExpr *) node;
3268 Node *raw_expr = (Node *) jve->raw_expr;
3269 Node *formatted_expr = (Node *) jve->formatted_expr;
3270
3271 /*
3272 * If we can fold formatted_expr to a constant, we can elide
3273 * the JsonValueExpr altogether. Otherwise we must process
3274 * raw_expr too. But JsonFormat is a flat node and requires
3275 * no simplification, only copying.
3276 */
3277 formatted_expr = eval_const_expressions_mutator(formatted_expr,
3278 context);
3279 if (formatted_expr && IsA(formatted_expr, Const))
3280 return formatted_expr;
3281
3282 raw_expr = eval_const_expressions_mutator(raw_expr, context);
3283
3284 return (Node *) makeJsonValueExpr((Expr *) raw_expr,
3285 (Expr *) formatted_expr,
3286 copyObject(jve->format));
3287 }
3289 {
3291
3292 /*
3293 * JSCTOR_JSON_ARRAY_QUERY carries a pre-built executable form
3294 * in its func field (a COALESCE-wrapped JSON_ARRAYAGG
3295 * subquery, constructed during parse analysis). Replace the
3296 * node with that expression and continue simplifying.
3297 */
3298 if (jce->type == JSCTOR_JSON_ARRAY_QUERY)
3299 return eval_const_expressions_mutator((Node *) jce->func,
3300 context);
3301 }
3302 break;
3303 case T_SubPlan:
3305
3306 /*
3307 * Return a SubPlan unchanged --- too late to do anything with it.
3308 *
3309 * XXX should we ereport() here instead? Probably this routine
3310 * should never be invoked after SubPlan creation.
3311 */
3312 return node;
3313 case T_RelabelType:
3314 {
3315 RelabelType *relabel = (RelabelType *) node;
3316 Node *arg;
3317
3318 /* Simplify the input ... */
3320 context);
3321 /* ... and attach a new RelabelType node, if needed */
3322 return applyRelabelType(arg,
3323 relabel->resulttype,
3324 relabel->resulttypmod,
3325 relabel->resultcollid,
3326 relabel->relabelformat,
3327 relabel->location,
3328 true);
3329 }
3330 case T_CoerceViaIO:
3331 {
3332 CoerceViaIO *expr = (CoerceViaIO *) node;
3333 List *args;
3334 Oid outfunc;
3335 bool outtypisvarlena;
3336 Oid infunc;
3338 Expr *simple;
3340
3341 /* Make a List so we can use simplify_function */
3342 args = list_make1(expr->arg);
3343
3344 /*
3345 * CoerceViaIO represents calling the source type's output
3346 * function then the result type's input function. So, try to
3347 * simplify it as though it were a stack of two such function
3348 * calls. First we need to know what the functions are.
3349 *
3350 * Note that the coercion functions are assumed not to care
3351 * about input collation, so we just pass InvalidOid for that.
3352 */
3356 &infunc, &intypioparam);
3357
3358 simple = simplify_function(outfunc,
3359 CSTRINGOID, -1,
3360 InvalidOid,
3361 InvalidOid,
3362 &args,
3363 false,
3364 true,
3365 true,
3366 context);
3367 if (simple) /* successfully simplified output fn */
3368 {
3369 /*
3370 * Input functions may want 1 to 3 arguments. We always
3371 * supply all three, trusting that nothing downstream will
3372 * complain.
3373 */
3374 args = list_make3(simple,
3376 -1,
3377 InvalidOid,
3378 sizeof(Oid),
3380 false,
3381 true),
3383 -1,
3384 InvalidOid,
3385 sizeof(int32),
3386 Int32GetDatum(-1),
3387 false,
3388 true));
3389
3390 simple = simplify_function(infunc,
3391 expr->resulttype, -1,
3392 expr->resultcollid,
3393 InvalidOid,
3394 &args,
3395 false,
3396 false,
3397 true,
3398 context);
3399 if (simple) /* successfully simplified input fn */
3400 return (Node *) simple;
3401 }
3402
3403 /*
3404 * The expression cannot be simplified any further, so build
3405 * and return a replacement CoerceViaIO node using the
3406 * possibly-simplified argument.
3407 */
3409 newexpr->arg = (Expr *) linitial(args);
3410 newexpr->resulttype = expr->resulttype;
3411 newexpr->resultcollid = expr->resultcollid;
3412 newexpr->coerceformat = expr->coerceformat;
3413 newexpr->location = expr->location;
3414 return (Node *) newexpr;
3415 }
3416 case T_ArrayCoerceExpr:
3417 {
3420
3421 /*
3422 * Copy the node and const-simplify its arguments. We can't
3423 * use ece_generic_processing() here because we need to mess
3424 * with case_val only while processing the elemexpr.
3425 */
3426 memcpy(ac, node, sizeof(ArrayCoerceExpr));
3427 ac->arg = (Expr *)
3429 context);
3430
3431 /*
3432 * Set up for the CaseTestExpr node contained in the elemexpr.
3433 * We must prevent it from absorbing any outer CASE value.
3434 */
3435 save_case_val = context->case_val;
3436 context->case_val = NULL;
3437
3438 ac->elemexpr = (Expr *)
3440 context);
3441
3442 context->case_val = save_case_val;
3443
3444 /*
3445 * If constant argument and the per-element expression is
3446 * immutable, we can simplify the whole thing to a constant.
3447 * Exception: although contain_mutable_functions considers
3448 * CoerceToDomain immutable for historical reasons, let's not
3449 * do so here; this ensures coercion to an array-over-domain
3450 * does not apply the domain's constraints until runtime.
3451 */
3452 if (ac->arg && IsA(ac->arg, Const) &&
3453 ac->elemexpr && !IsA(ac->elemexpr, CoerceToDomain) &&
3454 !contain_mutable_functions((Node *) ac->elemexpr))
3455 return ece_evaluate_expr(ac);
3456
3457 return (Node *) ac;
3458 }
3459 case T_CollateExpr:
3460 {
3461 /*
3462 * We replace CollateExpr with RelabelType, so as to improve
3463 * uniformity of expression representation and thus simplify
3464 * comparison of expressions. Hence this looks very nearly
3465 * the same as the RelabelType case, and we can apply the same
3466 * optimizations to avoid unnecessary RelabelTypes.
3467 */
3468 CollateExpr *collate = (CollateExpr *) node;
3469 Node *arg;
3470
3471 /* Simplify the input ... */
3473 context);
3474 /* ... and attach a new RelabelType node, if needed */
3475 return applyRelabelType(arg,
3476 exprType(arg),
3477 exprTypmod(arg),
3478 collate->collOid,
3480 collate->location,
3481 true);
3482 }
3483 case T_CaseExpr:
3484 {
3485 /*----------
3486 * CASE expressions can be simplified if there are constant
3487 * condition clauses:
3488 * FALSE (or NULL): drop the alternative
3489 * TRUE: drop all remaining alternatives
3490 * If the first non-FALSE alternative is a constant TRUE,
3491 * we can simplify the entire CASE to that alternative's
3492 * expression. If there are no non-FALSE alternatives,
3493 * we simplify the entire CASE to the default result (ELSE).
3494 *
3495 * If we have a simple-form CASE with constant test
3496 * expression, we substitute the constant value for contained
3497 * CaseTestExpr placeholder nodes, so that we have the
3498 * opportunity to reduce constant test conditions. For
3499 * example this allows
3500 * CASE 0 WHEN 0 THEN 1 ELSE 1/0 END
3501 * to reduce to 1 rather than drawing a divide-by-0 error.
3502 * Note that when the test expression is constant, we don't
3503 * have to include it in the resulting CASE; for example
3504 * CASE 0 WHEN x THEN y ELSE z END
3505 * is transformed by the parser to
3506 * CASE 0 WHEN CaseTestExpr = x THEN y ELSE z END
3507 * which we can simplify to
3508 * CASE WHEN 0 = x THEN y ELSE z END
3509 * It is not necessary for the executor to evaluate the "arg"
3510 * expression when executing the CASE, since any contained
3511 * CaseTestExprs that might have referred to it will have been
3512 * replaced by the constant.
3513 *----------
3514 */
3515 CaseExpr *caseexpr = (CaseExpr *) node;
3518 Node *newarg;
3519 List *newargs;
3520 bool const_true_cond;
3521 Node *defresult = NULL;
3522 ListCell *arg;
3523
3524 /* Simplify the test expression, if any */
3526 context);
3527
3528 /* Set up for contained CaseTestExpr nodes */
3529 save_case_val = context->case_val;
3530 if (newarg && IsA(newarg, Const))
3531 {
3532 context->case_val = newarg;
3533 newarg = NULL; /* not needed anymore, see above */
3534 }
3535 else
3536 context->case_val = NULL;
3537
3538 /* Simplify the WHEN clauses */
3539 newargs = NIL;
3540 const_true_cond = false;
3541 foreach(arg, caseexpr->args)
3542 {
3544 Node *casecond;
3546
3547 /* Simplify this alternative's test condition */
3549 context);
3550
3551 /*
3552 * If the test condition is constant FALSE (or NULL), then
3553 * drop this WHEN clause completely, without processing
3554 * the result.
3555 */
3556 if (casecond && IsA(casecond, Const))
3557 {
3559
3560 if (const_input->constisnull ||
3561 !DatumGetBool(const_input->constvalue))
3562 continue; /* drop alternative with FALSE cond */
3563 /* Else it's constant TRUE */
3564 const_true_cond = true;
3565 }
3566
3567 /* Simplify this alternative's result value */
3569 context);
3570
3571 /* If non-constant test condition, emit a new WHEN node */
3572 if (!const_true_cond)
3573 {
3575
3576 newcasewhen->expr = (Expr *) casecond;
3577 newcasewhen->result = (Expr *) caseresult;
3578 newcasewhen->location = oldcasewhen->location;
3580 continue;
3581 }
3582
3583 /*
3584 * Found a TRUE condition, so none of the remaining
3585 * alternatives can be reached. We treat the result as
3586 * the default result.
3587 */
3588 defresult = caseresult;
3589 break;
3590 }
3591
3592 /* Simplify the default result, unless we replaced it above */
3593 if (!const_true_cond)
3594 defresult = eval_const_expressions_mutator((Node *) caseexpr->defresult,
3595 context);
3596
3597 context->case_val = save_case_val;
3598
3599 /*
3600 * If no non-FALSE alternatives, CASE reduces to the default
3601 * result
3602 */
3603 if (newargs == NIL)
3604 return defresult;
3605 /* Otherwise we need a new CASE node */
3607 newcase->casetype = caseexpr->casetype;
3608 newcase->casecollid = caseexpr->casecollid;
3609 newcase->arg = (Expr *) newarg;
3610 newcase->args = newargs;
3611 newcase->defresult = (Expr *) defresult;
3612 newcase->location = caseexpr->location;
3613 return (Node *) newcase;
3614 }
3615 case T_CaseTestExpr:
3616 {
3617 /*
3618 * If we know a constant test value for the current CASE
3619 * construct, substitute it for the placeholder. Else just
3620 * return the placeholder as-is.
3621 */
3622 if (context->case_val)
3623 return copyObject(context->case_val);
3624 else
3625 return copyObject(node);
3626 }
3627 case T_SubscriptingRef:
3628 case T_ArrayExpr:
3629 case T_RowExpr:
3630 case T_MinMaxExpr:
3631 {
3632 /*
3633 * Generic handling for node types whose own processing is
3634 * known to be immutable, and for which we need no smarts
3635 * beyond "simplify if all inputs are constants".
3636 *
3637 * Treating SubscriptingRef this way assumes that subscripting
3638 * fetch and assignment are both immutable. This constrains
3639 * type-specific subscripting implementations; maybe we should
3640 * relax it someday.
3641 *
3642 * Treating MinMaxExpr this way amounts to assuming that the
3643 * btree comparison function it calls is immutable; see the
3644 * reasoning in contain_mutable_functions_walker.
3645 */
3646
3647 /* Copy the node and const-simplify its arguments */
3648 node = ece_generic_processing(node);
3649 /* If all arguments are Consts, we can fold to a constant */
3650 if (ece_all_arguments_const(node))
3651 return ece_evaluate_expr(node);
3652 return node;
3653 }
3654 case T_CoalesceExpr:
3655 {
3658 List *newargs;
3659 ListCell *arg;
3660
3661 newargs = NIL;
3662 foreach(arg, coalesceexpr->args)
3663 {
3664 Node *e;
3665
3667 context);
3668
3669 /*
3670 * We can remove null constants from the list. For a
3671 * nonnullable expression, if it has not been preceded by
3672 * any non-null-constant expressions then it is the
3673 * result. Otherwise, it's the next argument, but we can
3674 * drop following arguments since they will never be
3675 * reached.
3676 */
3677 if (IsA(e, Const))
3678 {
3679 if (((Const *) e)->constisnull)
3680 continue; /* drop null constant */
3681 if (newargs == NIL)
3682 return e; /* first expr */
3684 break;
3685 }
3686 if (expr_is_nonnullable(context->root, (Expr *) e,
3688 {
3689 if (newargs == NIL)
3690 return e; /* first expr */
3692 break;
3693 }
3694
3696 }
3697
3698 /*
3699 * If all the arguments were constant null, the result is just
3700 * null
3701 */
3702 if (newargs == NIL)
3703 return (Node *) makeNullConst(coalesceexpr->coalescetype,
3704 -1,
3705 coalesceexpr->coalescecollid);
3706
3707 /*
3708 * If there's exactly one surviving argument, we no longer
3709 * need COALESCE at all: the result is that argument
3710 */
3711 if (list_length(newargs) == 1)
3712 return (Node *) linitial(newargs);
3713
3715 newcoalesce->coalescetype = coalesceexpr->coalescetype;
3716 newcoalesce->coalescecollid = coalesceexpr->coalescecollid;
3717 newcoalesce->args = newargs;
3718 newcoalesce->location = coalesceexpr->location;
3719 return (Node *) newcoalesce;
3720 }
3721 case T_SQLValueFunction:
3722 {
3723 /*
3724 * All variants of SQLValueFunction are stable, so if we are
3725 * estimating the expression's value, we should evaluate the
3726 * current function value. Otherwise just copy.
3727 */
3728 SQLValueFunction *svf = (SQLValueFunction *) node;
3729
3730 if (context->estimate)
3731 return (Node *) evaluate_expr((Expr *) svf,
3732 svf->type,
3733 svf->typmod,
3734 InvalidOid);
3735 else
3736 return copyObject((Node *) svf);
3737 }
3738 case T_FieldSelect:
3739 {
3740 /*
3741 * We can optimize field selection from a whole-row Var into a
3742 * simple Var. (This case won't be generated directly by the
3743 * parser, because ParseComplexProjection short-circuits it.
3744 * But it can arise while simplifying functions.) Also, we
3745 * can optimize field selection from a RowExpr construct, or
3746 * of course from a constant.
3747 *
3748 * However, replacing a whole-row Var in this way has a
3749 * pitfall: if we've already built the rel targetlist for the
3750 * source relation, then the whole-row Var is scheduled to be
3751 * produced by the relation scan, but the simple Var probably
3752 * isn't, which will lead to a failure in setrefs.c. This is
3753 * not a problem when handling simple single-level queries, in
3754 * which expression simplification always happens first. It
3755 * is a risk for lateral references from subqueries, though.
3756 * To avoid such failures, don't optimize uplevel references.
3757 *
3758 * We must also check that the declared type of the field is
3759 * still the same as when the FieldSelect was created --- this
3760 * can change if someone did ALTER COLUMN TYPE on the rowtype.
3761 * If it isn't, we skip the optimization; the case will
3762 * probably fail at runtime, but that's not our problem here.
3763 */
3764 FieldSelect *fselect = (FieldSelect *) node;
3766 Node *arg;
3767
3769 context);
3770 if (arg && IsA(arg, Var) &&
3771 ((Var *) arg)->varattno == InvalidAttrNumber &&
3772 ((Var *) arg)->varlevelsup == 0)
3773 {
3774 if (rowtype_field_matches(((Var *) arg)->vartype,
3775 fselect->fieldnum,
3776 fselect->resulttype,
3777 fselect->resulttypmod,
3778 fselect->resultcollid))
3779 {
3780 Var *newvar;
3781
3782 newvar = makeVar(((Var *) arg)->varno,
3783 fselect->fieldnum,
3784 fselect->resulttype,
3785 fselect->resulttypmod,
3786 fselect->resultcollid,
3787 ((Var *) arg)->varlevelsup);
3788 /* New Var has same OLD/NEW returning as old one */
3789 newvar->varreturningtype = ((Var *) arg)->varreturningtype;
3790 /* New Var is nullable by same rels as the old one */
3791 newvar->varnullingrels = ((Var *) arg)->varnullingrels;
3792 return (Node *) newvar;
3793 }
3794 }
3795 if (arg && IsA(arg, RowExpr))
3796 {
3797 RowExpr *rowexpr = (RowExpr *) arg;
3798
3799 if (fselect->fieldnum > 0 &&
3800 fselect->fieldnum <= list_length(rowexpr->args))
3801 {
3802 Node *fld = (Node *) list_nth(rowexpr->args,
3803 fselect->fieldnum - 1);
3804
3805 if (rowtype_field_matches(rowexpr->row_typeid,
3806 fselect->fieldnum,
3807 fselect->resulttype,
3808 fselect->resulttypmod,
3809 fselect->resultcollid) &&
3810 fselect->resulttype == exprType(fld) &&
3811 fselect->resulttypmod == exprTypmod(fld) &&
3812 fselect->resultcollid == exprCollation(fld))
3813 return fld;
3814 }
3815 }
3817 newfselect->arg = (Expr *) arg;
3818 newfselect->fieldnum = fselect->fieldnum;
3819 newfselect->resulttype = fselect->resulttype;
3820 newfselect->resulttypmod = fselect->resulttypmod;
3821 newfselect->resultcollid = fselect->resultcollid;
3822 if (arg && IsA(arg, Const))
3823 {
3824 Const *con = (Const *) arg;
3825
3827 newfselect->fieldnum,
3828 newfselect->resulttype,
3829 newfselect->resulttypmod,
3830 newfselect->resultcollid))
3832 }
3833 return (Node *) newfselect;
3834 }
3835 case T_NullTest:
3836 {
3837 NullTest *ntest = (NullTest *) node;
3839 Node *arg;
3840
3842 context);
3843 if (ntest->argisrow && arg && IsA(arg, RowExpr))
3844 {
3845 /*
3846 * We break ROW(...) IS [NOT] NULL into separate tests on
3847 * its component fields. This form is usually more
3848 * efficient to evaluate, as well as being more amenable
3849 * to optimization.
3850 */
3851 RowExpr *rarg = (RowExpr *) arg;
3852 List *newargs = NIL;
3853 ListCell *l;
3854
3855 foreach(l, rarg->args)
3856 {
3857 Node *relem = (Node *) lfirst(l);
3858
3859 /*
3860 * A constant field refutes the whole NullTest if it's
3861 * of the wrong nullness; else we can discard it.
3862 */
3863 if (relem && IsA(relem, Const))
3864 {
3865 Const *carg = (Const *) relem;
3866
3867 if (carg->constisnull ?
3868 (ntest->nulltesttype == IS_NOT_NULL) :
3869 (ntest->nulltesttype == IS_NULL))
3870 return makeBoolConst(false, false);
3871 continue;
3872 }
3873
3874 /*
3875 * A proven non-nullable field refutes the whole
3876 * NullTest if the test is IS NULL; else we can
3877 * discard it.
3878 */
3879 if (relem &&
3880 expr_is_nonnullable(context->root, (Expr *) relem,
3882 {
3883 if (ntest->nulltesttype == IS_NULL)
3884 return makeBoolConst(false, false);
3885 continue;
3886 }
3887
3888 /*
3889 * Else, make a scalar (argisrow == false) NullTest
3890 * for this field. Scalar semantics are required
3891 * because IS [NOT] NULL doesn't recurse; see comments
3892 * in ExecEvalRowNullInt().
3893 */
3895 newntest->arg = (Expr *) relem;
3896 newntest->nulltesttype = ntest->nulltesttype;
3897 newntest->argisrow = false;
3898 newntest->location = ntest->location;
3900 }
3901 /* If all the inputs were constants, result is TRUE */
3902 if (newargs == NIL)
3903 return makeBoolConst(true, false);
3904 /* If only one nonconst input, it's the result */
3905 if (list_length(newargs) == 1)
3906 return (Node *) linitial(newargs);
3907 /* Else we need an AND node */
3908 return (Node *) make_andclause(newargs);
3909 }
3910 if (!ntest->argisrow && arg && IsA(arg, Const))
3911 {
3912 Const *carg = (Const *) arg;
3913 bool result;
3914
3915 switch (ntest->nulltesttype)
3916 {
3917 case IS_NULL:
3918 result = carg->constisnull;
3919 break;
3920 case IS_NOT_NULL:
3921 result = !carg->constisnull;
3922 break;
3923 default:
3924 elog(ERROR, "unrecognized nulltesttype: %d",
3925 (int) ntest->nulltesttype);
3926 result = false; /* keep compiler quiet */
3927 break;
3928 }
3929
3930 return makeBoolConst(result, false);
3931 }
3932 if (!ntest->argisrow && arg &&
3933 expr_is_nonnullable(context->root, (Expr *) arg,
3935 {
3936 bool result;
3937
3938 switch (ntest->nulltesttype)
3939 {
3940 case IS_NULL:
3941 result = false;
3942 break;
3943 case IS_NOT_NULL:
3944 result = true;
3945 break;
3946 default:
3947 elog(ERROR, "unrecognized nulltesttype: %d",
3948 (int) ntest->nulltesttype);
3949 result = false; /* keep compiler quiet */
3950 break;
3951 }
3952
3953 return makeBoolConst(result, false);
3954 }
3955
3957 newntest->arg = (Expr *) arg;
3958 newntest->nulltesttype = ntest->nulltesttype;
3959 newntest->argisrow = ntest->argisrow;
3960 newntest->location = ntest->location;
3961 return (Node *) newntest;
3962 }
3963 case T_BooleanTest:
3964 {
3965 /*
3966 * This case could be folded into the generic handling used
3967 * for ArrayExpr etc. But because the simplification logic is
3968 * so trivial, applying evaluate_expr() to perform it would be
3969 * a heavy overhead. BooleanTest is probably common enough to
3970 * justify keeping this bespoke implementation.
3971 */
3972 BooleanTest *btest = (BooleanTest *) node;
3974 Node *arg;
3975
3977 context);
3978 if (arg && IsA(arg, Const))
3979 {
3980 /*
3981 * If arg is Const, simplify to constant.
3982 */
3983 Const *carg = (Const *) arg;
3984 bool result;
3985
3986 switch (btest->booltesttype)
3987 {
3988 case IS_TRUE:
3989 result = (!carg->constisnull &&
3990 DatumGetBool(carg->constvalue));
3991 break;
3992 case IS_NOT_TRUE:
3993 result = (carg->constisnull ||
3994 !DatumGetBool(carg->constvalue));
3995 break;
3996 case IS_FALSE:
3997 result = (!carg->constisnull &&
3998 !DatumGetBool(carg->constvalue));
3999 break;
4000 case IS_NOT_FALSE:
4001 result = (carg->constisnull ||
4002 DatumGetBool(carg->constvalue));
4003 break;
4004 case IS_UNKNOWN:
4005 result = carg->constisnull;
4006 break;
4007 case IS_NOT_UNKNOWN:
4008 result = !carg->constisnull;
4009 break;
4010 default:
4011 elog(ERROR, "unrecognized booltesttype: %d",
4012 (int) btest->booltesttype);
4013 result = false; /* keep compiler quiet */
4014 break;
4015 }
4016
4017 return makeBoolConst(result, false);
4018 }
4019 if (arg &&
4020 expr_is_nonnullable(context->root, (Expr *) arg,
4022 {
4023 /*
4024 * If arg is proven non-nullable, simplify to boolean
4025 * expression or constant.
4026 */
4027 switch (btest->booltesttype)
4028 {
4029 case IS_TRUE:
4030 case IS_NOT_FALSE:
4031 return arg;
4032
4033 case IS_FALSE:
4034 case IS_NOT_TRUE:
4035 return (Node *) make_notclause((Expr *) arg);
4036
4037 case IS_UNKNOWN:
4038 return makeBoolConst(false, false);
4039
4040 case IS_NOT_UNKNOWN:
4041 return makeBoolConst(true, false);
4042
4043 default:
4044 elog(ERROR, "unrecognized booltesttype: %d",
4045 (int) btest->booltesttype);
4046 break;
4047 }
4048 }
4049
4051 newbtest->arg = (Expr *) arg;
4052 newbtest->booltesttype = btest->booltesttype;
4053 newbtest->location = btest->location;
4054 return (Node *) newbtest;
4055 }
4056 case T_CoerceToDomain:
4057 {
4058 /*
4059 * If the domain currently has no constraints, we replace the
4060 * CoerceToDomain node with a simple RelabelType, which is
4061 * both far faster to execute and more amenable to later
4062 * optimization. We must then mark the plan as needing to be
4063 * rebuilt if the domain's constraints change.
4064 *
4065 * Also, in estimation mode, always replace CoerceToDomain
4066 * nodes, effectively assuming that the coercion will succeed.
4067 */
4070 Node *arg;
4071
4073 context);
4074 if (context->estimate ||
4075 !DomainHasConstraints(cdomain->resulttype, NULL))
4076 {
4077 /* Record dependency, if this isn't estimation mode */
4078 if (context->root && !context->estimate)
4079 record_plan_type_dependency(context->root,
4080 cdomain->resulttype);
4081
4082 /* Generate RelabelType to substitute for CoerceToDomain */
4083 return applyRelabelType(arg,
4084 cdomain->resulttype,
4085 cdomain->resulttypmod,
4086 cdomain->resultcollid,
4087 cdomain->coercionformat,
4088 cdomain->location,
4089 true);
4090 }
4091
4093 newcdomain->arg = (Expr *) arg;
4094 newcdomain->resulttype = cdomain->resulttype;
4095 newcdomain->resulttypmod = cdomain->resulttypmod;
4096 newcdomain->resultcollid = cdomain->resultcollid;
4097 newcdomain->coercionformat = cdomain->coercionformat;
4098 newcdomain->location = cdomain->location;
4099 return (Node *) newcdomain;
4100 }
4101 case T_PlaceHolderVar:
4102
4103 /*
4104 * In estimation mode, just strip the PlaceHolderVar node
4105 * altogether; this amounts to estimating that the contained value
4106 * won't be forced to null by an outer join. In regular mode we
4107 * just use the default behavior (ie, simplify the expression but
4108 * leave the PlaceHolderVar node intact).
4109 */
4110 if (context->estimate)
4111 {
4112 PlaceHolderVar *phv = (PlaceHolderVar *) node;
4113
4114 return eval_const_expressions_mutator((Node *) phv->phexpr,
4115 context);
4116 }
4117 break;
4119 {
4121 Node *arg;
4123
4125 context);
4126
4128 newcre->resulttype = cre->resulttype;
4129 newcre->convertformat = cre->convertformat;
4130 newcre->location = cre->location;
4131
4132 /*
4133 * In case of a nested ConvertRowtypeExpr, we can convert the
4134 * leaf row directly to the topmost row format without any
4135 * intermediate conversions. (This works because
4136 * ConvertRowtypeExpr is used only for child->parent
4137 * conversion in inheritance trees, which works by exact match
4138 * of column name, and a column absent in an intermediate
4139 * result can't be present in the final result.)
4140 *
4141 * No need to check more than one level deep, because the
4142 * above recursion will have flattened anything else.
4143 */
4144 if (arg != NULL && IsA(arg, ConvertRowtypeExpr))
4145 {
4147
4148 arg = (Node *) argcre->arg;
4149
4150 /*
4151 * Make sure an outer implicit conversion can't hide an
4152 * inner explicit one.
4153 */
4154 if (newcre->convertformat == COERCE_IMPLICIT_CAST)
4155 newcre->convertformat = argcre->convertformat;
4156 }
4157
4158 newcre->arg = (Expr *) arg;
4159
4160 if (arg != NULL && IsA(arg, Const))
4161 return ece_evaluate_expr((Node *) newcre);
4162 return (Node *) newcre;
4163 }
4164 default:
4165 break;
4166 }
4167
4168 /*
4169 * For any node type not handled above, copy the node unchanged but
4170 * const-simplify its subexpressions. This is the correct thing for node
4171 * types whose behavior might change between planning and execution, such
4172 * as CurrentOfExpr. It's also a safe default for new node types not
4173 * known to this routine.
4174 */
4175 return ece_generic_processing(node);
4176}
4177
4178/*
4179 * Subroutine for eval_const_expressions: check for non-Const nodes.
4180 *
4181 * We can abort recursion immediately on finding a non-Const node. This is
4182 * critical for performance, else eval_const_expressions_mutator would take
4183 * O(N^2) time on non-simplifiable trees. However, we do need to descend
4184 * into List nodes since expression_tree_walker sometimes invokes the walker
4185 * function directly on List subtrees.
4186 */
4187static bool
4188contain_non_const_walker(Node *node, void *context)
4189{
4190 if (node == NULL)
4191 return false;
4192 if (IsA(node, Const))
4193 return false;
4194 if (IsA(node, List))
4195 return expression_tree_walker(node, contain_non_const_walker, context);
4196 /* Otherwise, abort the tree traversal and return true */
4197 return true;
4198}
4199
4200/*
4201 * Subroutine for eval_const_expressions: check if a function is OK to evaluate
4202 */
4203static bool
4205{
4206 char provolatile = func_volatile(funcid);
4207
4208 /*
4209 * Ordinarily we are only allowed to simplify immutable functions. But for
4210 * purposes of estimation, we consider it okay to simplify functions that
4211 * are merely stable; the risk that the result might change from planning
4212 * time to execution time is worth taking in preference to not being able
4213 * to estimate the value at all.
4214 */
4216 return true;
4217 if (context->estimate && provolatile == PROVOLATILE_STABLE)
4218 return true;
4219 return false;
4220}
4221
4222/*
4223 * Subroutine for eval_const_expressions: process arguments of an OR clause
4224 *
4225 * This includes flattening of nested ORs as well as recursion to
4226 * eval_const_expressions to simplify the OR arguments.
4227 *
4228 * After simplification, OR arguments are handled as follows:
4229 * non constant: keep
4230 * FALSE: drop (does not affect result)
4231 * TRUE: force result to TRUE
4232 * NULL: keep only one
4233 * We must keep one NULL input because OR expressions evaluate to NULL when no
4234 * input is TRUE and at least one is NULL. We don't actually include the NULL
4235 * here, that's supposed to be done by the caller.
4236 *
4237 * The output arguments *haveNull and *forceTrue must be initialized false
4238 * by the caller. They will be set true if a NULL constant or TRUE constant,
4239 * respectively, is detected anywhere in the argument list.
4240 */
4241static List *
4244 bool *haveNull, bool *forceTrue)
4245{
4246 List *newargs = NIL;
4248
4249 /*
4250 * We want to ensure that any OR immediately beneath another OR gets
4251 * flattened into a single OR-list, so as to simplify later reasoning.
4252 *
4253 * To avoid stack overflow from recursion of eval_const_expressions, we
4254 * resort to some tenseness here: we keep a list of not-yet-processed
4255 * inputs, and handle flattening of nested ORs by prepending to the to-do
4256 * list instead of recursing. Now that the parser generates N-argument
4257 * ORs from simple lists, this complexity is probably less necessary than
4258 * it once was, but we might as well keep the logic.
4259 */
4261 while (unprocessed_args)
4262 {
4264
4266
4267 /* flatten nested ORs as per above comment */
4268 if (is_orclause(arg))
4269 {
4270 List *subargs = ((BoolExpr *) arg)->args;
4272
4274 /* perhaps-overly-tense code to avoid leaking old lists */
4276 continue;
4277 }
4278
4279 /* If it's not an OR, simplify it */
4281
4282 /*
4283 * It is unlikely but not impossible for simplification of a non-OR
4284 * clause to produce an OR. Recheck, but don't be too tense about it
4285 * since it's not a mainstream case. In particular we don't worry
4286 * about const-simplifying the input twice, nor about list leakage.
4287 */
4288 if (is_orclause(arg))
4289 {
4290 List *subargs = ((BoolExpr *) arg)->args;
4291
4293 continue;
4294 }
4295
4296 /*
4297 * OK, we have a const-simplified non-OR argument. Process it per
4298 * comments above.
4299 */
4300 if (IsA(arg, Const))
4301 {
4302 Const *const_input = (Const *) arg;
4303
4304 if (const_input->constisnull)
4305 *haveNull = true;
4306 else if (DatumGetBool(const_input->constvalue))
4307 {
4308 *forceTrue = true;
4309
4310 /*
4311 * Once we detect a TRUE result we can just exit the loop
4312 * immediately. However, if we ever add a notion of
4313 * non-removable functions, we'd need to keep scanning.
4314 */
4315 return NIL;
4316 }
4317 /* otherwise, we can drop the constant-false input */
4318 continue;
4319 }
4320
4321 /* else emit the simplified arg into the result list */
4323 }
4324
4325 return newargs;
4326}
4327
4328/*
4329 * Subroutine for eval_const_expressions: process arguments of an AND clause
4330 *
4331 * This includes flattening of nested ANDs as well as recursion to
4332 * eval_const_expressions to simplify the AND arguments.
4333 *
4334 * After simplification, AND arguments are handled as follows:
4335 * non constant: keep
4336 * TRUE: drop (does not affect result)
4337 * FALSE: force result to FALSE
4338 * NULL: keep only one
4339 * We must keep one NULL input because AND expressions evaluate to NULL when
4340 * no input is FALSE and at least one is NULL. We don't actually include the
4341 * NULL here, that's supposed to be done by the caller.
4342 *
4343 * The output arguments *haveNull and *forceFalse must be initialized false
4344 * by the caller. They will be set true if a null constant or false constant,
4345 * respectively, is detected anywhere in the argument list.
4346 */
4347static List *
4350 bool *haveNull, bool *forceFalse)
4351{
4352 List *newargs = NIL;
4354
4355 /* See comments in simplify_or_arguments */
4357 while (unprocessed_args)
4358 {
4360
4362
4363 /* flatten nested ANDs as per above comment */
4364 if (is_andclause(arg))
4365 {
4366 List *subargs = ((BoolExpr *) arg)->args;
4368
4370 /* perhaps-overly-tense code to avoid leaking old lists */
4372 continue;
4373 }
4374
4375 /* If it's not an AND, simplify it */
4377
4378 /*
4379 * It is unlikely but not impossible for simplification of a non-AND
4380 * clause to produce an AND. Recheck, but don't be too tense about it
4381 * since it's not a mainstream case. In particular we don't worry
4382 * about const-simplifying the input twice, nor about list leakage.
4383 */
4384 if (is_andclause(arg))
4385 {
4386 List *subargs = ((BoolExpr *) arg)->args;
4387
4389 continue;
4390 }
4391
4392 /*
4393 * OK, we have a const-simplified non-AND argument. Process it per
4394 * comments above.
4395 */
4396 if (IsA(arg, Const))
4397 {
4398 Const *const_input = (Const *) arg;
4399
4400 if (const_input->constisnull)
4401 *haveNull = true;
4402 else if (!DatumGetBool(const_input->constvalue))
4403 {
4404 *forceFalse = true;
4405
4406 /*
4407 * Once we detect a FALSE result we can just exit the loop
4408 * immediately. However, if we ever add a notion of
4409 * non-removable functions, we'd need to keep scanning.
4410 */
4411 return NIL;
4412 }
4413 /* otherwise, we can drop the constant-true input */
4414 continue;
4415 }
4416
4417 /* else emit the simplified arg into the result list */
4419 }
4420
4421 return newargs;
4422}
4423
4424/*
4425 * Subroutine for eval_const_expressions: try to simplify boolean equality
4426 * or inequality condition
4427 *
4428 * Inputs are the operator OID and the simplified arguments to the operator.
4429 * Returns a simplified expression if successful, or NULL if cannot
4430 * simplify the expression.
4431 *
4432 * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x",
4433 * or similarly "x <> true" to "NOT x" and "x <> false" to "x".
4434 * This is only marginally useful in itself, but doing it in constant folding
4435 * ensures that we will recognize these forms as being equivalent in, for
4436 * example, partial index matching.
4437 *
4438 * We come here only if simplify_function has failed; therefore we cannot
4439 * see two constant inputs, nor a constant-NULL input.
4440 */
4441static Node *
4443{
4444 Node *leftop;
4445 Node *rightop;
4446
4447 Assert(list_length(args) == 2);
4448 leftop = linitial(args);
4449 rightop = lsecond(args);
4450 if (leftop && IsA(leftop, Const))
4451 {
4452 Assert(!((Const *) leftop)->constisnull);
4453 if (opno == BooleanEqualOperator)
4454 {
4455 if (DatumGetBool(((Const *) leftop)->constvalue))
4456 return rightop; /* true = foo */
4457 else
4458 return negate_clause(rightop); /* false = foo */
4459 }
4460 else
4461 {
4462 if (DatumGetBool(((Const *) leftop)->constvalue))
4463 return negate_clause(rightop); /* true <> foo */
4464 else
4465 return rightop; /* false <> foo */
4466 }
4467 }
4468 if (rightop && IsA(rightop, Const))
4469 {
4471 if (opno == BooleanEqualOperator)
4472 {
4474 return leftop; /* foo = true */
4475 else
4476 return negate_clause(leftop); /* foo = false */
4477 }
4478 else
4479 {
4481 return negate_clause(leftop); /* foo <> true */
4482 else
4483 return leftop; /* foo <> false */
4484 }
4485 }
4486 return NULL;
4487}
4488
4489/*
4490 * Subroutine for eval_const_expressions: try to simplify a function call
4491 * (which might originally have been an operator; we don't care)
4492 *
4493 * Inputs are the function OID, actual result type OID (which is needed for
4494 * polymorphic functions), result typmod, result collation, the input
4495 * collation to use for the function, the original argument list (not
4496 * const-simplified yet, unless process_args is false), and some flags;
4497 * also the context data for eval_const_expressions.
4498 *
4499 * Returns a simplified expression if successful, or NULL if cannot
4500 * simplify the function call.
4501 *
4502 * This function is also responsible for converting named-notation argument
4503 * lists into positional notation and/or adding any needed default argument
4504 * expressions; which is a bit grotty, but it avoids extra fetches of the
4505 * function's pg_proc tuple. For this reason, the args list is
4506 * pass-by-reference. Conversion and const-simplification of the args list
4507 * will be done even if simplification of the function call itself is not
4508 * possible.
4509 */
4510static Expr *
4511simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
4513 bool funcvariadic, bool process_args, bool allow_non_const,
4515{
4516 List *args = *args_p;
4519 Expr *newexpr;
4520
4521 /*
4522 * We have three strategies for simplification: execute the function to
4523 * deliver a constant result, use a transform function to generate a
4524 * substitute node tree, or expand in-line the body of the function
4525 * definition (which only works for simple SQL-language functions, but
4526 * that is a common case). Each case needs access to the function's
4527 * pg_proc tuple, so fetch it just once.
4528 *
4529 * Note: the allow_non_const flag suppresses both the second and third
4530 * strategies; so if !allow_non_const, simplify_function can only return a
4531 * Const or NULL. Argument-list rewriting happens anyway, though.
4532 */
4535 elog(ERROR, "cache lookup failed for function %u", funcid);
4537
4538 /*
4539 * Process the function arguments, unless the caller did it already.
4540 *
4541 * Here we must deal with named or defaulted arguments, and then
4542 * recursively apply eval_const_expressions to the whole argument list.
4543 */
4544 if (process_args)
4545 {
4546 args = expand_function_arguments(args, false, result_type, func_tuple);
4549 context);
4550 /* Argument processing done, give it back to the caller */
4551 *args_p = args;
4552 }
4553
4554 /* Now attempt simplification of the function call proper. */
4555
4556 newexpr = evaluate_function(funcid, result_type, result_typmod,
4558 args, funcvariadic,
4559 func_tuple, context);
4560
4561 if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport))
4562 {
4563 /*
4564 * Build a SupportRequestSimplify node to pass to the support
4565 * function, pointing to a dummy FuncExpr node containing the
4566 * simplified arg list. We use this approach to present a uniform
4567 * interface to the support function regardless of how the target
4568 * function is actually being invoked.
4569 */
4572
4573 fexpr.xpr.type = T_FuncExpr;
4574 fexpr.funcid = funcid;
4575 fexpr.funcresulttype = result_type;
4576 fexpr.funcretset = func_form->proretset;
4577 fexpr.funcvariadic = funcvariadic;
4578 fexpr.funcformat = COERCE_EXPLICIT_CALL;
4579 fexpr.funccollid = result_collid;
4580 fexpr.inputcollid = input_collid;
4581 fexpr.args = args;
4582 fexpr.location = -1;
4583
4585 req.root = context->root;
4586 req.fcall = &fexpr;
4587
4588 newexpr = (Expr *)
4590 PointerGetDatum(&req)));
4591
4592 /* catch a possible API misunderstanding */
4593 Assert(newexpr != (Expr *) &fexpr);
4594 }
4595
4596 if (!newexpr && allow_non_const)
4597 newexpr = inline_function(funcid, result_type, result_collid,
4599 func_tuple, context);
4600
4602
4603 return newexpr;
4604}
4605
4606/*
4607 * simplify_aggref
4608 * Call the Aggref.aggfnoid's prosupport function to allow it to
4609 * determine if simplification of the Aggref is possible. Returns the
4610 * newly simplified node if conversion took place; otherwise, returns the
4611 * original Aggref.
4612 *
4613 * See SupportRequestSimplifyAggref comments in supportnodes.h for further
4614 * details.
4615 */
4616static Node *
4618{
4620
4622 {
4624 Node *newnode;
4625
4626 /*
4627 * Build a SupportRequestSimplifyAggref node to pass to the support
4628 * function.
4629 */
4631 req.root = context->root;
4632 req.aggref = aggref;
4633
4635 PointerGetDatum(&req)));
4636
4637 /*
4638 * We expect the support function to return either a new Node or NULL
4639 * (when simplification isn't possible).
4640 */
4641 Assert(newnode != (Node *) aggref || newnode == NULL);
4642
4643 if (newnode != NULL)
4644 return newnode;
4645 }
4646
4647 return (Node *) aggref;
4648}
4649
4650/*
4651 * var_is_nonnullable: check to see if the Var cannot be NULL
4652 *
4653 * If the Var is defined NOT NULL and meanwhile is not nulled by any outer
4654 * joins or grouping sets, then we can know that it cannot be NULL.
4655 *
4656 * "source" specifies where we should look for NOT NULL proofs.
4657 */
4658bool
4660{
4661 Assert(IsA(var, Var));
4662
4663 /* skip upper-level Vars */
4664 if (var->varlevelsup != 0)
4665 return false;
4666
4667 /* could the Var be nulled by any outer joins or grouping sets? */
4668 if (!bms_is_empty(var->varnullingrels))
4669 return false;
4670
4671 /*
4672 * If the Var has a non-default returning type, it could be NULL
4673 * regardless of any NOT NULL constraint. For example, OLD.col is NULL
4674 * for INSERT, and NEW.col is NULL for DELETE.
4675 */
4677 return false;
4678
4679 /* system columns cannot be NULL */
4680 if (var->varattno < 0)
4681 return true;
4682
4683 /* we don't trust whole-row Vars */
4684 if (var->varattno == 0)
4685 return false;
4686
4687 /* Check if the Var is defined as NOT NULL. */
4688 switch (source)
4689 {
4691 {
4692 /*
4693 * We retrieve the column NOT NULL constraint information from
4694 * the corresponding RelOptInfo.
4695 */
4696 RelOptInfo *rel;
4697 Bitmapset *notnullattnums;
4698
4699 rel = find_base_rel(root, var->varno);
4700 notnullattnums = rel->notnullattnums;
4701
4702 return bms_is_member(var->varattno, notnullattnums);
4703 }
4705 {
4706 /*
4707 * We retrieve the column NOT NULL constraint information from
4708 * the hash table.
4709 */
4711 Bitmapset *notnullattnums;
4712
4713 rte = planner_rt_fetch(var->varno, root);
4714
4715 /* We can only reason about ordinary relations */
4716 if (rte->rtekind != RTE_RELATION)
4717 return false;
4718
4719 /*
4720 * We must skip inheritance parent tables, as some child
4721 * tables may have a NOT NULL constraint for a column while
4722 * others may not. This cannot happen with partitioned
4723 * tables, though.
4724 */
4725 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4726 return false;
4727
4728 notnullattnums = find_relation_notnullatts(root, rte->relid);
4729
4730 return bms_is_member(var->varattno, notnullattnums);
4731 }
4733 {
4734 /*
4735 * We check the attnullability field in the tuple descriptor.
4736 * This is necessary rather than checking the attnotnull field
4737 * from the attribute relation, because attnotnull is also set
4738 * for invalid (NOT VALID) NOT NULL constraints, which do not
4739 * guarantee the absence of NULLs.
4740 */
4742 Relation rel;
4743 CompactAttribute *attr;
4744 bool result;
4745
4746 rte = planner_rt_fetch(var->varno, root);
4747
4748 /* We can only reason about ordinary relations */
4749 if (rte->rtekind != RTE_RELATION)
4750 return false;
4751
4752 /*
4753 * We must skip inheritance parent tables, as some child
4754 * tables may have a NOT NULL constraint for a column while
4755 * others may not. This cannot happen with partitioned
4756 * tables, though.
4757 *
4758 * Note that we need to check if the relation actually has any
4759 * children, as we might not have done that yet.
4760 */
4761 if (rte->inh && has_subclass(rte->relid) &&
4762 rte->relkind != RELKIND_PARTITIONED_TABLE)
4763 return false;
4764
4765 /* We need not lock the relation since it was already locked */
4766 rel = table_open(rte->relid, NoLock);
4768 var->varattno - 1);
4770 table_close(rel, NoLock);
4771
4772 return result;
4773 }
4774 default:
4775 elog(ERROR, "unrecognized NotNullSource: %d",
4776 (int) source);
4777 break;
4778 }
4779
4780 return false;
4781}
4782
4783/*
4784 * expr_is_nonnullable: check to see if the Expr cannot be NULL
4785 *
4786 * Returns true iff the given 'expr' cannot produce SQL NULLs.
4787 *
4788 * source: specifies where we should look for NOT NULL proofs for Vars.
4789 * - NOTNULL_SOURCE_RELOPT: Used when RelOptInfos have been generated. We
4790 * retrieve nullability information directly from the RelOptInfo corresponding
4791 * to the Var.
4792 * - NOTNULL_SOURCE_HASHTABLE: Used when RelOptInfos are not yet available,
4793 * but we have already collected relation-level not-null constraints into the
4794 * global hash table.
4795 * - NOTNULL_SOURCE_CATALOG: Used for raw parse trees where neither
4796 * RelOptInfos nor the hash table are available. In this case, we check the
4797 * column's attnullability in the tuple descriptor.
4798 *
4799 * For now, we support only a limited set of expression types. Support for
4800 * additional node types can be added in the future.
4801 */
4802bool
4804{
4805 /* since this function recurses, it could be driven to stack overflow */
4807
4808 switch (nodeTag(expr))
4809 {
4810 case T_Var:
4811 {
4812 if (root)
4813 return var_is_nonnullable(root, (Var *) expr, source);
4814 }
4815 break;
4816 case T_Const:
4817 return !((Const *) expr)->constisnull;
4818 case T_CoalesceExpr:
4819 {
4820 /*
4821 * A CoalesceExpr returns NULL if and only if all its
4822 * arguments are NULL. Therefore, we can determine that a
4823 * CoalesceExpr cannot be NULL if at least one of its
4824 * arguments can be proven non-nullable.
4825 */
4827
4829 {
4831 return true;
4832 }
4833 }
4834 break;
4835 case T_MinMaxExpr:
4836 {
4837 /*
4838 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4839 * its arguments evaluate to NULL.
4840 */
4841 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4842
4844 {
4846 return true;
4847 }
4848 }
4849 break;
4850 case T_CaseExpr:
4851 {
4852 /*
4853 * A CASE expression is non-nullable if all branch results are
4854 * non-nullable. We must also verify that the default result
4855 * (ELSE) exists and is non-nullable.
4856 */
4857 CaseExpr *caseexpr = (CaseExpr *) expr;
4858
4859 /* The default result must be present and non-nullable */
4860 if (caseexpr->defresult == NULL ||
4861 !expr_is_nonnullable(root, caseexpr->defresult, source))
4862 return false;
4863
4864 /* All branch results must be non-nullable */
4866 {
4867 if (!expr_is_nonnullable(root, casewhen->result, source))
4868 return false;
4869 }
4870
4871 return true;
4872 }
4873 break;
4874 case T_ArrayExpr:
4875 {
4876 /*
4877 * An ARRAY[] expression always returns a valid Array object,
4878 * even if it is empty (ARRAY[]) or contains NULLs
4879 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4880 */
4881 return true;
4882 }
4883 case T_NullTest:
4884 {
4885 /*
4886 * An IS NULL / IS NOT NULL expression always returns a
4887 * boolean value. It never returns SQL NULL.
4888 */
4889 return true;
4890 }
4891 case T_BooleanTest:
4892 {
4893 /*
4894 * A BooleanTest expression always evaluates to a boolean
4895 * value. It never returns SQL NULL.
4896 */
4897 return true;
4898 }
4899 case T_DistinctExpr:
4900 {
4901 /*
4902 * IS DISTINCT FROM never returns NULL, effectively acting as
4903 * though NULL were a normal data value.
4904 */
4905 return true;
4906 }
4907 case T_RelabelType:
4908 {
4909 /*
4910 * RelabelType does not change the nullability of the data.
4911 * The result is non-nullable if and only if the argument is
4912 * non-nullable.
4913 */
4914 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4915 source);
4916 }
4917 default:
4918 break;
4919 }
4920
4921 return false;
4922}
4923
4924/*
4925 * expand_function_arguments: convert named-notation args to positional args
4926 * and/or insert default args, as needed
4927 *
4928 * Returns a possibly-transformed version of the args list.
4929 *
4930 * If include_out_arguments is true, then the args list and the result
4931 * include OUT arguments.
4932 *
4933 * The expected result type of the call must be given, for sanity-checking
4934 * purposes. Also, we ask the caller to provide the function's actual
4935 * pg_proc tuple, not just its OID.
4936 *
4937 * If we need to change anything, the input argument list is copied, not
4938 * modified.
4939 *
4940 * Note: this gets applied to operator argument lists too, even though the
4941 * cases it handles should never occur there. This should be OK since it
4942 * will fall through very quickly if there's nothing to do.
4943 */
4944List *
4946 Oid result_type, HeapTuple func_tuple)
4947{
4949 Oid *proargtypes = funcform->proargtypes.values;
4950 int pronargs = funcform->pronargs;
4951 bool has_named_args = false;
4952 ListCell *lc;
4953
4954 /*
4955 * If we are asked to match to OUT arguments, then use the proallargtypes
4956 * array (which includes those); otherwise use proargtypes (which
4957 * doesn't). Of course, if proallargtypes is null, we always use
4958 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4959 * considering that we may have nothing to do here, but fortunately the
4960 * common case is include_out_arguments == false.)
4961 */
4963 {
4965 bool isNull;
4966
4969 &isNull);
4970 if (!isNull)
4971 {
4973
4974 pronargs = ARR_DIMS(arr)[0];
4975 if (ARR_NDIM(arr) != 1 ||
4976 pronargs < 0 ||
4977 ARR_HASNULL(arr) ||
4978 ARR_ELEMTYPE(arr) != OIDOID)
4979 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4980 Assert(pronargs >= funcform->pronargs);
4981 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4982 }
4983 }
4984
4985 /* Do we have any named arguments? */
4986 foreach(lc, args)
4987 {
4988 Node *arg = (Node *) lfirst(lc);
4989
4990 if (IsA(arg, NamedArgExpr))
4991 {
4992 has_named_args = true;
4993 break;
4994 }
4995 }
4996
4997 /* If so, we must apply reorder_function_arguments */
4998 if (has_named_args)
4999 {
5001 /* Recheck argument types and add casts if needed */
5002 recheck_cast_function_args(args, result_type,
5004 func_tuple);
5005 }
5006 else if (list_length(args) < pronargs)
5007 {
5008 /* No named args, but we seem to be short some defaults */
5010 /* Recheck argument types and add casts if needed */
5011 recheck_cast_function_args(args, result_type,
5013 func_tuple);
5014 }
5015
5016 return args;
5017}
5018
5019/*
5020 * reorder_function_arguments: convert named-notation args to positional args
5021 *
5022 * This function also inserts default argument values as needed, since it's
5023 * impossible to form a truly valid positional call without that.
5024 */
5025static List *
5027{
5029 int nargsprovided = list_length(args);
5031 ListCell *lc;
5032 int i;
5033
5036 elog(ERROR, "too many function arguments");
5037 memset(argarray, 0, pronargs * sizeof(Node *));
5038
5039 /* Deconstruct the argument list into an array indexed by argnumber */
5040 i = 0;
5041 foreach(lc, args)
5042 {
5043 Node *arg = (Node *) lfirst(lc);
5044
5045 if (!IsA(arg, NamedArgExpr))
5046 {
5047 /* positional argument, assumed to precede all named args */
5048 Assert(argarray[i] == NULL);
5049 argarray[i++] = arg;
5050 }
5051 else
5052 {
5054
5055 Assert(na->argnumber >= 0 && na->argnumber < pronargs);
5056 Assert(argarray[na->argnumber] == NULL);
5057 argarray[na->argnumber] = (Node *) na->arg;
5058 }
5059 }
5060
5061 /*
5062 * Fetch default expressions, if needed, and insert into array at proper
5063 * locations (they aren't necessarily consecutive or all used)
5064 */
5065 if (nargsprovided < pronargs)
5066 {
5068
5069 i = pronargs - funcform->pronargdefaults;
5070 foreach(lc, defaults)
5071 {
5072 if (argarray[i] == NULL)
5073 argarray[i] = (Node *) lfirst(lc);
5074 i++;
5075 }
5076 }
5077
5078 /* Now reconstruct the args list in proper order */
5079 args = NIL;
5080 for (i = 0; i < pronargs; i++)
5081 {
5082 Assert(argarray[i] != NULL);
5083 args = lappend(args, argarray[i]);
5084 }
5085
5086 return args;
5087}
5088
5089/*
5090 * add_function_defaults: add missing function arguments from its defaults
5091 *
5092 * This is used only when the argument list was positional to begin with,
5093 * and so we know we just need to add defaults at the end.
5094 */
5095static List *
5097{
5098 int nargsprovided = list_length(args);
5099 List *defaults;
5100 int ndelete;
5101
5102 /* Get all the default expressions from the pg_proc tuple */
5104
5105 /* Delete any unused defaults from the list */
5106 ndelete = nargsprovided + list_length(defaults) - pronargs;
5107 if (ndelete < 0)
5108 elog(ERROR, "not enough default arguments");
5109 if (ndelete > 0)
5110 defaults = list_delete_first_n(defaults, ndelete);
5111
5112 /* And form the combined argument list, not modifying the input list */
5113 return list_concat_copy(args, defaults);
5114}
5115
5116/*
5117 * fetch_function_defaults: get function's default arguments as expression list
5118 */
5119static List *
5121{
5122 List *defaults;
5124 char *str;
5125
5129 defaults = castNode(List, stringToNode(str));
5130 pfree(str);
5131 return defaults;
5132}
5133
5134/*
5135 * recheck_cast_function_args: recheck function args and typecast as needed
5136 * after adding defaults.
5137 *
5138 * It is possible for some of the defaulted arguments to be polymorphic;
5139 * therefore we can't assume that the default expressions have the correct
5140 * data types already. We have to re-resolve polymorphics and do coercion
5141 * just like the parser did.
5142 *
5143 * This should be a no-op if there are no polymorphic arguments,
5144 * but we do it anyway to be sure.
5145 *
5146 * Note: if any casts are needed, the args list is modified in-place;
5147 * caller should have already copied the list structure.
5148 */
5149static void
5150recheck_cast_function_args(List *args, Oid result_type,
5151 Oid *proargtypes, int pronargs,
5153{
5155 int nargs;
5158 Oid rettype;
5159 ListCell *lc;
5160
5161 if (list_length(args) > FUNC_MAX_ARGS)
5162 elog(ERROR, "too many function arguments");
5163 nargs = 0;
5164 foreach(lc, args)
5165 {
5166 actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));
5167 }
5168 Assert(nargs == pronargs);
5172 nargs,
5173 funcform->prorettype,
5174 false);
5175 /* let's just check we got the same answer as the parser did ... */
5176 if (rettype != result_type)
5177 elog(ERROR, "function's resolved result type changed during planning");
5178
5179 /* perform any necessary typecasting of arguments */
5181}
5182
5183/*
5184 * evaluate_function: try to pre-evaluate a function call
5185 *
5186 * We can do this if the function is strict and has any constant-null inputs
5187 * (just return a null constant), or if the function is immutable and has all
5188 * constant inputs (call it and return the result as a Const node). In
5189 * estimation mode we are willing to pre-evaluate stable functions too.
5190 *
5191 * Returns a simplified expression if successful, or NULL if cannot
5192 * simplify the function.
5193 */
5194static Expr *
5195evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
5197 bool funcvariadic,
5200{
5202 bool has_nonconst_input = false;
5203 bool has_null_input = false;
5204 ListCell *arg;
5206
5207 /*
5208 * Can't simplify if it returns a set.
5209 */
5210 if (funcform->proretset)
5211 return NULL;
5212
5213 /*
5214 * Can't simplify if it returns RECORD. The immediate problem is that it
5215 * will be needing an expected tupdesc which we can't supply here.
5216 *
5217 * In the case where it has OUT parameters, we could build an expected
5218 * tupdesc from those, but there may be other gotchas lurking. In
5219 * particular, if the function were to return NULL, we would produce a
5220 * null constant with no remaining indication of which concrete record
5221 * type it is. For now, seems best to leave the function call unreduced.
5222 */
5223 if (funcform->prorettype == RECORDOID)
5224 return NULL;
5225
5226 /*
5227 * Check for constant inputs and especially constant-NULL inputs.
5228 */
5229 foreach(arg, args)
5230 {
5231 if (IsA(lfirst(arg), Const))
5233 else
5234 has_nonconst_input = true;
5235 }
5236
5237 /*
5238 * If the function is strict and has a constant-NULL input, it will never
5239 * be called at all, so we can replace the call by a NULL constant, even
5240 * if there are other inputs that aren't constant, and even if the
5241 * function is not otherwise immutable.
5242 */
5243 if (funcform->proisstrict && has_null_input)
5244 return (Expr *) makeNullConst(result_type, result_typmod,
5246
5247 /*
5248 * Otherwise, can simplify only if all inputs are constants. (For a
5249 * non-strict function, constant NULL inputs are treated the same as
5250 * constant non-NULL inputs.)
5251 */
5253 return NULL;
5254
5255 /*
5256 * Ordinarily we are only allowed to simplify immutable functions. But for
5257 * purposes of estimation, we consider it okay to simplify functions that
5258 * are merely stable; the risk that the result might change from planning
5259 * time to execution time is worth taking in preference to not being able
5260 * to estimate the value at all.
5261 */
5262 if (funcform->provolatile == PROVOLATILE_IMMUTABLE)
5263 /* okay */ ;
5264 else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE)
5265 /* okay */ ;
5266 else
5267 return NULL;
5268
5269 /*
5270 * OK, looks like we can simplify this operator/function.
5271 *
5272 * Build a new FuncExpr node containing the already-simplified arguments.
5273 */
5275 newexpr->funcid = funcid;
5276 newexpr->funcresulttype = result_type;
5277 newexpr->funcretset = false;
5278 newexpr->funcvariadic = funcvariadic;
5279 newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5280 newexpr->funccollid = result_collid; /* doesn't matter */
5281 newexpr->inputcollid = input_collid;
5282 newexpr->args = args;
5283 newexpr->location = -1;
5284
5285 return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
5287}
5288
5289/*
5290 * inline_function: try to expand a function call inline
5291 *
5292 * If the function is a sufficiently simple SQL-language function
5293 * (just "SELECT expression"), then we can inline it and avoid the rather
5294 * high per-call overhead of SQL functions. Furthermore, this can expose
5295 * opportunities for constant-folding within the function expression.
5296 *
5297 * We have to beware of some special cases however. A directly or
5298 * indirectly recursive function would cause us to recurse forever,
5299 * so we keep track of which functions we are already expanding and
5300 * do not re-expand them. Also, if a parameter is used more than once
5301 * in the SQL-function body, we require it not to contain any volatile
5302 * functions (volatiles might deliver inconsistent answers) nor to be
5303 * unreasonably expensive to evaluate. The expensiveness check not only
5304 * prevents us from doing multiple evaluations of an expensive parameter
5305 * at runtime, but is a safety value to limit growth of an expression due
5306 * to repeated inlining.
5307 *
5308 * We must also beware of changing the volatility or strictness status of
5309 * functions by inlining them.
5310 *
5311 * Also, at the moment we can't inline functions returning RECORD. This
5312 * doesn't work in the general case because it discards information such
5313 * as OUT-parameter declarations.
5314 *
5315 * Also, context-dependent expression nodes in the argument list are trouble.
5316 *
5317 * Returns a simplified expression if successful, or NULL if cannot
5318 * simplify the function.
5319 */
5320static Expr *
5321inline_function(Oid funcid, Oid result_type, Oid result_collid,
5322 Oid input_collid, List *args,
5323 bool funcvariadic,
5326{
5328 char *src;
5329 Datum tmp;
5330 bool isNull;
5333 inline_error_callback_arg callback_arg;
5335 FuncExpr *fexpr;
5337 TupleDesc rettupdesc;
5338 ParseState *pstate;
5342 Node *newexpr;
5343 int *usecounts;
5344 ListCell *arg;
5345 int i;
5346
5347 /*
5348 * Forget it if the function is not SQL-language or has other showstopper
5349 * properties. (The prokind and nargs checks are just paranoia.)
5350 */
5351 if (funcform->prolang != SQLlanguageId ||
5352 funcform->prokind != PROKIND_FUNCTION ||
5353 funcform->prosecdef ||
5354 funcform->proretset ||
5355 funcform->prorettype == RECORDOID ||
5357 funcform->pronargs != list_length(args))
5358 return NULL;
5359
5360 /* Check for recursive function, and give up trying to expand if so */
5361 if (list_member_oid(context->active_fns, funcid))
5362 return NULL;
5363
5364 /* Check permission to call function (fail later, if not) */
5366 return NULL;
5367
5368 /* Check whether a plugin wants to hook function entry/exit */
5369 if (FmgrHookIsNeeded(funcid))
5370 return NULL;
5371
5372 /*
5373 * Make a temporary memory context, so that we don't leak all the stuff
5374 * that parsing might create.
5375 */
5377 "inline_function",
5380
5381 /*
5382 * We need a dummy FuncExpr node containing the already-simplified
5383 * arguments. (In some cases we don't really need it, but building it is
5384 * cheap enough that it's not worth contortions to avoid.)
5385 */
5387 fexpr->funcid = funcid;
5388 fexpr->funcresulttype = result_type;
5389 fexpr->funcretset = false;
5390 fexpr->funcvariadic = funcvariadic;
5391 fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5392 fexpr->funccollid = result_collid; /* doesn't matter */
5393 fexpr->inputcollid = input_collid;
5394 fexpr->args = args;
5395 fexpr->location = -1;
5396
5397 /* Fetch the function body */
5399 src = TextDatumGetCString(tmp);
5400
5401 /*
5402 * Setup error traceback support for ereport(). This is so that we can
5403 * finger the function that bad information came from.
5404 */
5405 callback_arg.proname = NameStr(funcform->proname);
5406 callback_arg.prosrc = src;
5407
5409 sqlerrcontext.arg = &callback_arg;
5412
5413 /* If we have prosqlbody, pay attention to that not prosrc */
5415 func_tuple,
5417 &isNull);
5418 if (!isNull)
5419 {
5420 Node *n;
5421 List *query_list;
5422
5424 if (IsA(n, List))
5425 query_list = linitial_node(List, castNode(List, n));
5426 else
5427 query_list = list_make1(n);
5428 if (list_length(query_list) != 1)
5429 goto fail;
5430 querytree = linitial(query_list);
5431
5432 /*
5433 * Because we'll insist below that the querytree have an empty rtable
5434 * and no sublinks, it cannot have any relation references that need
5435 * to be locked or rewritten. So we can omit those steps.
5436 */
5437 }
5438 else
5439 {
5440 /* Set up to handle parameters while parsing the function body. */
5442 (Node *) fexpr,
5443 input_collid);
5444
5445 /*
5446 * We just do parsing and parse analysis, not rewriting, because
5447 * rewriting will not affect table-free-SELECT-only queries, which is
5448 * all that we care about. Also, we can punt as soon as we detect
5449 * more than one command in the function body.
5450 */
5453 goto fail;
5454
5455 pstate = make_parsestate(NULL);
5456 pstate->p_sourcetext = src;
5457 sql_fn_parser_setup(pstate, pinfo);
5458
5460
5461 free_parsestate(pstate);
5462 }
5463
5464 /*
5465 * The single command must be a simple "SELECT expression".
5466 *
5467 * Note: if you change the tests involved in this, see also plpgsql's
5468 * exec_simple_check_plan(). That generally needs to have the same idea
5469 * of what's a "simple expression", so that inlining a function that
5470 * previously wasn't inlined won't change plpgsql's conclusion.
5471 */
5472 if (!IsA(querytree, Query) ||
5473 querytree->commandType != CMD_SELECT ||
5474 querytree->hasAggs ||
5475 querytree->hasWindowFuncs ||
5476 querytree->hasTargetSRFs ||
5477 querytree->hasSubLinks ||
5478 querytree->cteList ||
5479 querytree->rtable ||
5480 querytree->jointree->fromlist ||
5481 querytree->jointree->quals ||
5482 querytree->groupClause ||
5483 querytree->groupingSets ||
5484 querytree->havingQual ||
5485 querytree->windowClause ||
5486 querytree->distinctClause ||
5487 querytree->sortClause ||
5488 querytree->limitOffset ||
5489 querytree->limitCount ||
5490 querytree->setOperations ||
5491 list_length(querytree->targetList) != 1)
5492 goto fail;
5493
5494 /* If the function result is composite, resolve it */
5496 NULL,
5497 &rettupdesc);
5498
5499 /*
5500 * Make sure the function (still) returns what it's declared to. This
5501 * will raise an error if wrong, but that's okay since the function would
5502 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5503 * a coercion if needed to make the tlist expression match the declared
5504 * type of the function.
5505 *
5506 * Note: we do not try this until we have verified that no rewriting was
5507 * needed; that's probably not important, but let's be careful.
5508 */
5511 result_type, rettupdesc,
5512 funcform->prokind,
5513 false))
5514 goto fail; /* reject whole-tuple-result cases */
5515
5516 /*
5517 * Given the tests above, check_sql_fn_retval shouldn't have decided to
5518 * inject a projection step, but let's just make sure.
5519 */
5521 goto fail;
5522
5523 /* Now we can grab the tlist expression */
5524 newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
5525
5526 /*
5527 * If the SQL function returns VOID, we can only inline it if it is a
5528 * SELECT of an expression returning VOID (ie, it's just a redirection to
5529 * another VOID-returning function). In all non-VOID-returning cases,
5530 * check_sql_fn_retval should ensure that newexpr returns the function's
5531 * declared result type, so this test shouldn't fail otherwise; but we may
5532 * as well cope gracefully if it does.
5533 */
5534 if (exprType(newexpr) != result_type)
5535 goto fail;
5536
5537 /*
5538 * Additional validity checks on the expression. It mustn't be more
5539 * volatile than the surrounding function (this is to avoid breaking hacks
5540 * that involve pretending a function is immutable when it really ain't).
5541 * If the surrounding function is declared strict, then the expression
5542 * must contain only strict constructs and must use all of the function
5543 * parameters (this is overkill, but an exact analysis is hard).
5544 */
5545 if (funcform->provolatile == PROVOLATILE_IMMUTABLE &&
5547 goto fail;
5548 else if (funcform->provolatile == PROVOLATILE_STABLE &&
5550 goto fail;
5551
5552 if (funcform->proisstrict &&
5554 goto fail;
5555
5556 /*
5557 * If any parameter expression contains a context-dependent node, we can't
5558 * inline, for fear of putting such a node into the wrong context.
5559 */
5561 goto fail;
5562
5563 /*
5564 * We may be able to do it; there are still checks on parameter usage to
5565 * make, but those are most easily done in combination with the actual
5566 * substitution of the inputs. So start building expression with inputs
5567 * substituted.
5568 */
5569 usecounts = (int *) palloc0(funcform->pronargs * sizeof(int));
5571 args, usecounts);
5572
5573 /* Now check for parameter usage */
5574 i = 0;
5575 foreach(arg, args)
5576 {
5577 Node *param = lfirst(arg);
5578
5579 if (usecounts[i] == 0)
5580 {
5581 /* Param not used at all: uncool if func is strict */
5582 if (funcform->proisstrict)
5583 goto fail;
5584 }
5585 else if (usecounts[i] != 1)
5586 {
5587 /* Param used multiple times: uncool if expensive or volatile */
5589
5590 /*
5591 * We define "expensive" as "contains any subplan or more than 10
5592 * operators". Note that the subplan search has to be done
5593 * explicitly, since cost_qual_eval() will barf on unplanned
5594 * subselects.
5595 */
5596 if (contain_subplans(param))
5597 goto fail;
5599 if (eval_cost.startup + eval_cost.per_tuple >
5600 10 * cpu_operator_cost)
5601 goto fail;
5602
5603 /*
5604 * Check volatility last since this is more expensive than the
5605 * above tests
5606 */
5607 if (contain_volatile_functions(param))
5608 goto fail;
5609 }
5610 i++;
5611 }
5612
5613 /*
5614 * Whew --- we can make the substitution. Copy the modified expression
5615 * out of the temporary memory context, and clean up.
5616 */
5618
5620
5622
5623 /*
5624 * If the result is of a collatable type, force the result to expose the
5625 * correct collation. In most cases this does not matter, but it's
5626 * possible that the function result is used directly as a sort key or in
5627 * other places where we expect exprCollation() to tell the truth.
5628 */
5630 {
5632
5634 {
5636
5637 newnode->arg = (Expr *) newexpr;
5638 newnode->collOid = result_collid;
5639 newnode->location = -1;
5640
5641 newexpr = (Node *) newnode;
5642 }
5643 }
5644
5645 /*
5646 * Since there is now no trace of the function in the plan tree, we must
5647 * explicitly record the plan's dependency on the function.
5648 */
5649 if (context->root)
5650 record_plan_function_dependency(context->root, funcid);
5651
5652 /*
5653 * Recursively try to simplify the modified expression. Here we must add
5654 * the current function to the context list of active functions.
5655 */
5656 context->active_fns = lappend_oid(context->active_fns, funcid);
5658 context->active_fns = list_delete_last(context->active_fns);
5659
5661
5662 return (Expr *) newexpr;
5663
5664 /* Here if func is not inlinable: release temp memory and return NULL */
5665fail:
5669
5670 return NULL;
5671}
5672
5673/*
5674 * Replace Param nodes by appropriate actual parameters
5675 */
5676static Node *
5677substitute_actual_parameters(Node *expr, int nargs, List *args,
5678 int *usecounts)
5679{
5681
5682 context.nargs = nargs;
5683 context.args = args;
5684 context.usecounts = usecounts;
5685
5686 return substitute_actual_parameters_mutator(expr, &context);
5687}
5688
5689static Node *
5692{
5693 if (node == NULL)
5694 return NULL;
5695 if (IsA(node, Param))
5696 {
5697 Param *param = (Param *) node;
5698
5699 if (param->paramkind != PARAM_EXTERN)
5700 elog(ERROR, "unexpected paramkind: %d", (int) param->paramkind);
5701 if (param->paramid <= 0 || param->paramid > context->nargs)
5702 elog(ERROR, "invalid paramid: %d", param->paramid);
5703
5704 /* Count usage of parameter */
5705 context->usecounts[param->paramid - 1]++;
5706
5707 /* Select the appropriate actual arg and replace the Param with it */
5708 /* We don't need to copy at this time (it'll get done later) */
5709 return list_nth(context->args, param->paramid - 1);
5710 }
5712}
5713
5714/*
5715 * error context callback to let us supply a call-stack traceback
5716 */
5717static void
5719{
5722
5723 /* If it's a syntax error, convert to internal syntax error report */
5725 if (syntaxerrposition > 0)
5726 {
5727 errposition(0);
5729 internalerrquery(callback_arg->prosrc);
5730 }
5731
5732 errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
5733}
5734
5735/*
5736 * evaluate_expr: pre-evaluate a constant expression
5737 *
5738 * We use the executor's routine ExecEvalExpr() to avoid duplication of
5739 * code and ensure we get the same result as the executor would get.
5740 */
5741Expr *
5742evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
5744{
5745 EState *estate;
5746 ExprState *exprstate;
5747 MemoryContext oldcontext;
5749 bool const_is_null;
5751 bool resultTypByVal;
5752
5753 /*
5754 * To use the executor, we need an EState.
5755 */
5756 estate = CreateExecutorState();
5757
5758 /* We can use the estate's working context to avoid memory leaks. */
5759 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5760
5761 /* Make sure any opfuncids are filled in. */
5762 fix_opfuncids((Node *) expr);
5763
5764 /*
5765 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5766 * because it'd result in recursively invoking eval_const_expressions.)
5767 */
5768 exprstate = ExecInitExpr(expr, NULL);
5769
5770 /*
5771 * And evaluate it.
5772 *
5773 * It is OK to use a default econtext because none of the ExecEvalExpr()
5774 * code used in this situation will use econtext. That might seem
5775 * fortuitous, but it's not so unreasonable --- a constant expression does
5776 * not depend on context, by definition, n'est ce pas?
5777 */
5779 GetPerTupleExprContext(estate),
5780 &const_is_null);
5781
5782 /* Get info needed about result datatype */
5784
5785 /* Get back to outer memory context */
5786 MemoryContextSwitchTo(oldcontext);
5787
5788 /*
5789 * Must copy result out of sub-context used by expression eval.
5790 *
5791 * Also, if it's varlena, forcibly detoast it. This protects us against
5792 * storing TOAST pointers into plans that might outlive the referenced
5793 * data. (makeConst would handle detoasting anyway, but it's worth a few
5794 * extra lines here so that we can do the copy and detoast in one step.)
5795 */
5796 if (!const_is_null)
5797 {
5798 if (resultTypLen == -1)
5800 else
5802 }
5803
5804 /* Release all the junk we just created */
5805 FreeExecutorState(estate);
5806
5807 /*
5808 * Make the constant result node.
5809 */
5810 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5814}
5815
5816
5817/*
5818 * inline_function_in_from
5819 * Attempt to "inline" a function in the FROM clause.
5820 *
5821 * "rte" is an RTE_FUNCTION rangetable entry. If it represents a call of a
5822 * function that can be inlined, expand the function and return the
5823 * substitute Query structure. Otherwise, return NULL.
5824 *
5825 * We assume that the RTE's expression has already been put through
5826 * eval_const_expressions(), which among other things will take care of
5827 * default arguments and named-argument notation.
5828 *
5829 * This has a good deal of similarity to inline_function(), but that's
5830 * for the general-expression case, and there are enough differences to
5831 * justify separate functions.
5832 */
5833Query *
5835{
5836 RangeTblFunction *rtfunc;
5837 FuncExpr *fexpr;
5838 Oid func_oid;
5843 Datum tmp;
5844 char *src;
5845 inline_error_callback_arg callback_arg;
5847 Query *querytree = NULL;
5848
5849 Assert(rte->rtekind == RTE_FUNCTION);
5850
5851 /*
5852 * Guard against infinite recursion during expansion by checking for stack
5853 * overflow. (There's no need to do more.)
5854 */
5856
5857 /* Fail if the RTE has ORDINALITY - we don't implement that here. */
5858 if (rte->funcordinality)
5859 return NULL;
5860
5861 /* Fail if RTE isn't a single, simple FuncExpr */
5862 if (list_length(rte->functions) != 1)
5863 return NULL;
5864 rtfunc = (RangeTblFunction *) linitial(rte->functions);
5865
5866 if (!IsA(rtfunc->funcexpr, FuncExpr))
5867 return NULL;
5868 fexpr = (FuncExpr *) rtfunc->funcexpr;
5869
5870 func_oid = fexpr->funcid;
5871
5872 /*
5873 * Refuse to inline if the arguments contain any volatile functions or
5874 * sub-selects. Volatile functions are rejected because inlining may
5875 * result in the arguments being evaluated multiple times, risking a
5876 * change in behavior. Sub-selects are rejected partly for implementation
5877 * reasons (pushing them down another level might change their behavior)
5878 * and partly because they're likely to be expensive and so multiple
5879 * evaluation would be bad.
5880 */
5881 if (contain_volatile_functions((Node *) fexpr->args) ||
5882 contain_subplans((Node *) fexpr->args))
5883 return NULL;
5884
5885 /* Check permission to call function (fail later, if not) */
5887 return NULL;
5888
5889 /* Check whether a plugin wants to hook function entry/exit */
5891 return NULL;
5892
5893 /*
5894 * OK, let's take a look at the function's pg_proc entry.
5895 */
5898 elog(ERROR, "cache lookup failed for function %u", func_oid);
5900
5901 /*
5902 * If the function SETs any configuration parameters, inlining would cause
5903 * us to miss making those changes.
5904 */
5906 {
5908 return NULL;
5909 }
5910
5911 /*
5912 * Make a temporary memory context, so that we don't leak all the stuff
5913 * that parsing and rewriting might create. If we succeed, we'll copy
5914 * just the finished query tree back up to the caller's context.
5915 */
5917 "inline_function_in_from",
5920
5921 /* Fetch the function body */
5923 src = TextDatumGetCString(tmp);
5924
5925 /*
5926 * If the function has an attached support function that can handle
5927 * SupportRequestInlineInFrom, then attempt to inline with that.
5928 */
5929 if (funcform->prosupport)
5930 {
5932
5934 req.root = root;
5935 req.rtfunc = rtfunc;
5936 req.proc = func_tuple;
5937
5938 querytree = (Query *)
5940 PointerGetDatum(&req)));
5941 }
5942
5943 /*
5944 * Setup error traceback support for ereport(). This is so that we can
5945 * finger the function that bad information came from. We don't install
5946 * this while running the support function, since it'd be likely to do the
5947 * wrong thing: any parse errors reported during that are very likely not
5948 * against the raw function source text.
5949 */
5950 callback_arg.proname = NameStr(funcform->proname);
5951 callback_arg.prosrc = src;
5952
5954 sqlerrcontext.arg = &callback_arg;
5957
5958 /*
5959 * If SupportRequestInlineInFrom didn't work, try our built-in inlining
5960 * mechanism.
5961 */
5962 if (!querytree)
5964 func_tuple, funcform, src);
5965
5966 if (!querytree)
5967 goto fail; /* no luck there either, fail */
5968
5969 /*
5970 * The result had better be a SELECT Query.
5971 */
5973 Assert(querytree->commandType == CMD_SELECT);
5974
5975 /*
5976 * Looks good --- substitute parameters into the query.
5977 */
5979 funcform->pronargs,
5980 fexpr->args);
5981
5982 /*
5983 * Copy the modified query out of the temporary memory context, and clean
5984 * up.
5985 */
5987
5989
5993
5994 /*
5995 * We don't have to fix collations here because the upper query is already
5996 * parsed, ie, the collations in the RTE are what count.
5997 */
5998
5999 /*
6000 * Since there is now no trace of the function in the plan tree, we must
6001 * explicitly record the plan's dependency on the function.
6002 */
6004
6005 /*
6006 * We must also notice if the inserted query adds a dependency on the
6007 * calling role due to RLS quals.
6008 */
6009 if (querytree->hasRowSecurity)
6010 root->glob->dependsOnRole = true;
6011
6012 return querytree;
6013
6014 /* Here if func is not inlinable: release temp memory and return NULL */
6015fail:
6020
6021 return NULL;
6022}
6023
6024/*
6025 * inline_sql_function_in_from
6026 *
6027 * This implements inline_function_in_from for SQL-language functions.
6028 * Returns NULL if the function couldn't be inlined.
6029 *
6030 * The division of labor between here and inline_function_in_from is based
6031 * on the rule that inline_function_in_from should make all checks that are
6032 * certain to be required in both this case and the support-function case.
6033 * Support functions might also want to make checks analogous to the ones
6034 * made here, but then again they might not, or they might just assume that
6035 * the function they are attached to can validly be inlined.
6036 */
6037static Query *
6039 RangeTblFunction *rtfunc,
6040 FuncExpr *fexpr,
6043 const char *src)
6044{
6045 Datum sqlbody;
6046 bool isNull;
6050 TupleDesc rettupdesc;
6051
6052 /*
6053 * The function must be declared to return a set, else inlining would
6054 * change the results if the contained SELECT didn't return exactly one
6055 * row.
6056 */
6057 if (!fexpr->funcretset)
6058 return NULL;
6059
6060 /*
6061 * Forget it if the function is not SQL-language or has other showstopper
6062 * properties. In particular it mustn't be declared STRICT, since we
6063 * couldn't enforce that. It also mustn't be VOLATILE, because that is
6064 * supposed to cause it to be executed with its own snapshot, rather than
6065 * sharing the snapshot of the calling query. We also disallow returning
6066 * SETOF VOID, because inlining would result in exposing the actual result
6067 * of the function's last SELECT, which should not happen in that case.
6068 * (Rechecking prokind, proretset, and pronargs is just paranoia.)
6069 */
6070 if (funcform->prolang != SQLlanguageId ||
6071 funcform->prokind != PROKIND_FUNCTION ||
6072 funcform->proisstrict ||
6073 funcform->provolatile == PROVOLATILE_VOLATILE ||
6074 funcform->prorettype == VOIDOID ||
6075 funcform->prosecdef ||
6076 !funcform->proretset ||
6077 list_length(fexpr->args) != funcform->pronargs)
6078 return NULL;
6079
6080 /* If we have prosqlbody, pay attention to that not prosrc */
6082 func_tuple,
6084 &isNull);
6085 if (!isNull)
6086 {
6087 Node *n;
6088
6090 if (IsA(n, List))
6092 else
6094 if (list_length(querytree_list) != 1)
6095 return NULL;
6097
6098 /* Acquire necessary locks, then apply rewriter. */
6099 AcquireRewriteLocks(querytree, true, false);
6101 if (list_length(querytree_list) != 1)
6102 return NULL;
6104 }
6105 else
6106 {
6109
6110 /*
6111 * Set up to handle parameters while parsing the function body. We
6112 * can use the FuncExpr just created as the input for
6113 * prepare_sql_fn_parse_info.
6114 */
6116 (Node *) fexpr,
6117 fexpr->inputcollid);
6118
6119 /*
6120 * Parse, analyze, and rewrite (unlike inline_function(), we can't
6121 * skip rewriting here). We can fail as soon as we find more than one
6122 * query, though.
6123 */
6126 return NULL;
6127
6129 src,
6131 pinfo, NULL);
6132 if (list_length(querytree_list) != 1)
6133 return NULL;
6135 }
6136
6137 /*
6138 * Also resolve the actual function result tupdesc, if composite. If we
6139 * have a coldeflist, believe that; otherwise use get_expr_result_type.
6140 * (This logic should match ExecInitFunctionScan.)
6141 */
6142 if (rtfunc->funccolnames != NIL)
6143 {
6145 rettupdesc = BuildDescFromLists(rtfunc->funccolnames,
6146 rtfunc->funccoltypes,
6147 rtfunc->funccoltypmods,
6148 rtfunc->funccolcollations);
6149 }
6150 else
6151 functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc);
6152
6153 /*
6154 * The single command must be a plain SELECT.
6155 */
6156 if (!IsA(querytree, Query) ||
6157 querytree->commandType != CMD_SELECT)
6158 return NULL;
6159
6160 /*
6161 * Make sure the function (still) returns what it's declared to. This
6162 * will raise an error if wrong, but that's okay since the function would
6163 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
6164 * coercions if needed to make the tlist expression(s) match the declared
6165 * type of the function. We also ask it to insert dummy NULL columns for
6166 * any dropped columns in rettupdesc, so that the elements of the modified
6167 * tlist match up to the attribute numbers.
6168 *
6169 * If the function returns a composite type, don't inline unless the check
6170 * shows it's returning a whole tuple result; otherwise what it's
6171 * returning is a single composite column which is not what we need.
6172 */
6174 fexpr->funcresulttype, rettupdesc,
6175 funcform->prokind,
6176 true) &&
6180 return NULL; /* reject not-whole-tuple-result cases */
6181
6182 /*
6183 * check_sql_fn_retval might've inserted a projection step, but that's
6184 * fine; just make sure we use the upper Query.
6185 */
6187
6188 return querytree;
6189}
6190
6191/*
6192 * Replace Param nodes by appropriate actual parameters
6193 *
6194 * This is just enough different from substitute_actual_parameters()
6195 * that it needs its own code.
6196 */
6197static Query *
6198substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
6199{
6201
6202 context.nargs = nargs;
6203 context.args = args;
6204 context.sublevels_up = 1;
6205
6206 return query_tree_mutator(expr,
6208 &context,
6209 0);
6210}
6211
6212static Node *
6215{
6216 Node *result;
6217
6218 if (node == NULL)
6219 return NULL;
6220 if (IsA(node, Query))
6221 {
6222 context->sublevels_up++;
6223 result = (Node *) query_tree_mutator((Query *) node,
6225 context,
6226 0);
6227 context->sublevels_up--;
6228 return result;
6229 }
6230 if (IsA(node, Param))
6231 {
6232 Param *param = (Param *) node;
6233
6234 if (param->paramkind == PARAM_EXTERN)
6235 {
6236 if (param->paramid <= 0 || param->paramid > context->nargs)
6237 elog(ERROR, "invalid paramid: %d", param->paramid);
6238
6239 /*
6240 * Since the parameter is being inserted into a subquery, we must
6241 * adjust levels.
6242 */
6243 result = copyObject(list_nth(context->args, param->paramid - 1));
6245 return result;
6246 }
6247 }
6248 return expression_tree_mutator(node,
6250 context);
6251}
6252
6253/*
6254 * pull_paramids
6255 * Returns a Bitmapset containing the paramids of all Params in 'expr'.
6256 */
6257Bitmapset *
6258pull_paramids(Expr *expr)
6259{
6261
6262 (void) pull_paramids_walker((Node *) expr, &result);
6263
6264 return result;
6265}
6266
6267static bool
6268pull_paramids_walker(Node *node, Bitmapset **context)
6269{
6270 if (node == NULL)
6271 return false;
6272 if (IsA(node, Param))
6273 {
6274 Param *param = (Param *) node;
6275
6276 *context = bms_add_member(*context, param->paramid);
6277 return false;
6278 }
6279 return expression_tree_walker(node, pull_paramids_walker, context);
6280}
6281
6282/*
6283 * expression_has_grouping_conflict
6284 * Detect whether 'expr' would distinguish rows that a grouping mechanism
6285 * (GROUP BY, DISTINCT, DISTINCT ON, window PARTITION BY, or set operation)
6286 * considers equal.
6287 *
6288 * The caller supplies a get_eqop callback (see clauses.h) so the same walker
6289 * serves every grouping context. The callback identifies a grouping column by
6290 * returning a valid eqop for its Var. A grouping column is safe to reference
6291 * only if the reference yields the same result for every value the grouping
6292 * treats as equal. Otherwise, pushing the clause past the grouping could
6293 * discard rows that the grouping would have combined into a single group.
6294 *
6295 * The reference is provably safe only when the grouping column is a direct
6296 * operand of a comparison that tests the grouping's own equality. Such an
6297 * operand is rejected when the comparison's operator does not have equality
6298 * semantics compatible with the grouping eqop, or, for a nondeterministic
6299 * collation, when the comparison applies a collation other than the column's.
6300 *
6301 * For a nondeterministic collation, every other reference is rejected: a
6302 * comparison under a different collation, and any function or operator over
6303 * the column, because we cannot tell whether the function yields the same
6304 * result for values the grouping treats as equal, and many do not. A column
6305 * with a deterministic collation is not restricted this way.
6306 *
6307 * This leaves one case uncaught: with a deterministic collation, a function
6308 * over the column can still feed a finer comparison than the direct-operand
6309 * check sees, for example record_image_ops over a rebuilt record, or scale()
6310 * over numeric where two equal values differ in scale. Catching it would
6311 * require knowing that a type's equality is bitwise, which we do not test
6312 * here.
6313 *
6314 * Returns true if any such conflict exists.
6315 */
6316bool
6318 grouping_eqop_callback get_eqop,
6319 void *context)
6320{
6322
6323 if (expr == NULL)
6324 return false;
6325
6326 ctx.get_eqop = get_eqop;
6327 ctx.cb_context = context;
6328
6329 return grouping_conflict_walker(expr, &ctx);
6330}
6331
6332/*
6333 * Walker function for expression_has_grouping_conflict.
6334 *
6335 * A comparison node checks its direct operands with grouping_check_operand,
6336 * which does not recurse into a grouping-column operand. A grouping column
6337 * therefore reaches the Var branch only when it is referenced in some other
6338 * way: wrapped in a function or other expression, used as the whole qual (a
6339 * bare boolean column), or used as an operand of an operator that is not a
6340 * btree/hash member and so is not treated as a comparison here.
6341 *
6342 * Comparison nodes are OpExpr/ScalarArrayOpExpr whose operator is a btree/hash
6343 * member, and RowCompareExpr (one operator and collation per column). A
6344 * simple CASE (CaseExpr with a non-NULL arg) is a comparison in disguise:
6345 * parse analysis builds each WHEN as "OpExpr(CaseTestExpr op val)", with the
6346 * CaseTestExpr standing in for the arg, so the arg is effectively an operand
6347 * of each WHEN's comparison. Those WHEN operators are always the type-default
6348 * "=", matching the grouping eqop, so only a collation conflict is possible
6349 * there.
6350 */
6351static bool
6353{
6354 if (node == NULL)
6355 return false;
6356
6357 if (IsA(node, Var))
6358 {
6359 Var *var = (Var *) node;
6360
6361 /*
6362 * A grouping column reaches here when it was not handled as a direct
6363 * operand by a comparison node above (see the function header). That
6364 * is safe for a deterministic collation, but not for a
6365 * nondeterministic one, where the reference may distinguish values
6366 * the grouping considers equal. A bare boolean qual is safe too:
6367 * boolean is not collatable, so it takes the deterministic path here.
6368 */
6369 if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) &&
6370 OidIsValid(var->varcollid) &&
6371 !get_collation_isdeterministic(var->varcollid))
6372 return true;
6373 return false;
6374 }
6375 else if (IsA(node, OpExpr))
6376 {
6377 OpExpr *opexpr = (OpExpr *) node;
6378
6379 if (op_is_safe_index_member(opexpr->opno))
6380 return grouping_check_operands(opexpr->opno, opexpr->inputcollid,
6381 opexpr->args, ctx);
6382 /* fall through */
6383 }
6384 else if (IsA(node, ScalarArrayOpExpr))
6385 {
6386 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node;
6387
6388 if (op_is_safe_index_member(saop->opno))
6389 return grouping_check_operands(saop->opno, saop->inputcollid,
6390 saop->args, ctx);
6391 /* fall through */
6392 }
6393 else if (IsA(node, RowCompareExpr))
6394 {
6396 ListCell *lc_l;
6397 ListCell *lc_r;
6398 ListCell *lc_o;
6399 ListCell *lc_c;
6400
6401 /* Each column is compared under its own operator and inputcollid. */
6402 forfour(lc_l, rcexpr->largs,
6403 lc_r, rcexpr->rargs,
6404 lc_o, rcexpr->opnos,
6405 lc_c, rcexpr->inputcollids)
6406 {
6407 Oid opno = lfirst_oid(lc_o);
6409
6410 if (grouping_check_operand((Node *) lfirst(lc_l), opno, collid, ctx) ||
6411 grouping_check_operand((Node *) lfirst(lc_r), opno, collid, ctx))
6412 return true;
6413 }
6414 return false;
6415 }
6416 else if (IsA(node, CaseExpr) && ((CaseExpr *) node)->arg != NULL)
6417 {
6418 CaseExpr *cexpr = (CaseExpr *) node;
6419 Node *arg = (Node *) cexpr->arg;
6420
6421 /* Look through RelabelType to find a direct Var arg. */
6422 while (arg && IsA(arg, RelabelType))
6423 arg = (Node *) ((RelabelType *) arg)->arg;
6424
6425 if (arg && IsA(arg, Var))
6426 {
6427 Var *var = (Var *) arg;
6428
6429 /*
6430 * The arg is a grouping column compared by every WHEN. For a
6431 * nondeterministic collation, reject if any WHEN applies a
6432 * different collation.
6433 */
6434 if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) &&
6435 OidIsValid(var->varcollid) &&
6436 !get_collation_isdeterministic(var->varcollid))
6437 {
6438 foreach_node(CaseWhen, cw, cexpr->args)
6439 {
6440 Oid collid = exprInputCollation((Node *) cw->expr);
6441
6442 if (OidIsValid(collid) && collid != var->varcollid)
6443 return true;
6444 }
6445 }
6446 }
6447 else if (grouping_conflict_walker((Node *) cexpr->arg, ctx))
6448 {
6449 /* arg is a complex expression; walked as a non-operand */
6450 return true;
6451 }
6452
6453 /*
6454 * Walk the WHEN conditions, their results, and the default result as
6455 * non-operands. The WHEN conditions hold a CaseTestExpr in place of
6456 * the arg, so they contribute no grouping operand of their own, but
6457 * the condition expression or the substitution result may reference
6458 * another grouping column.
6459 */
6460 foreach_node(CaseWhen, cw, cexpr->args)
6461 {
6462 if (grouping_conflict_walker((Node *) cw->expr, ctx) ||
6463 grouping_conflict_walker((Node *) cw->result, ctx))
6464 return true;
6465 }
6466 return grouping_conflict_walker((Node *) cexpr->defresult, ctx);
6467 }
6468
6470}
6471
6472/*
6473 * grouping_check_operands
6474 * Check every argument of a comparison node as a direct operand of the
6475 * comparison's operator 'opno' and collation 'inputcollid'.
6476 */
6477static bool
6478grouping_check_operands(Oid opno, Oid inputcollid, List *args,
6480{
6481 ListCell *lc;
6482
6483 foreach(lc, args)
6484 {
6485 if (grouping_check_operand((Node *) lfirst(lc), opno, inputcollid, ctx))
6486 return true;
6487 }
6488 return false;
6489}
6490
6491/*
6492 * grouping_check_operand
6493 * Handle one operand 'arg' of a comparison with operator 'opno' and
6494 * collation 'inputcollid'.
6495 *
6496 * If 'arg' is a grouping column (after looking through RelabelType), verify
6497 * that comparison's operator has equality semantics compatible with the
6498 * grouping eqop and, for a nondeterministic collation, that it uses the same
6499 * collation; such a direct operand is then fully handled and is not recursed
6500 * into. Any other operand is walked normally, so a grouping column buried
6501 * inside it is seen as a non-operand reference.
6502 */
6503static bool
6504grouping_check_operand(Node *arg, Oid opno, Oid inputcollid,
6506{
6507 Node *node = arg;
6508
6509 while (node && IsA(node, RelabelType))
6510 node = (Node *) ((RelabelType *) node)->arg;
6511
6512 if (node && IsA(node, Var))
6513 {
6514 Var *var = (Var *) node;
6515 Oid grouping_eqop = ctx->get_eqop(var, ctx->cb_context);
6516
6518 {
6519 /* incompatible equality semantics */
6521 return true;
6522 /* nondeterministic collation compared under a different collation */
6523 if (OidIsValid(var->varcollid) &&
6524 !get_collation_isdeterministic(var->varcollid) &&
6525 inputcollid != var->varcollid)
6526 return true;
6527 }
6528 return false; /* direct operand handled; do not recurse */
6529 }
6530
6531 return grouping_conflict_walker(arg, ctx);
6532}
6533
6534/*
6535 * Build ScalarArrayOpExpr on top of 'exprs.' 'haveNonConst' indicates
6536 * whether at least one of the expressions is not Const. When it's false,
6537 * the array constant is built directly; otherwise, we have to build a child
6538 * ArrayExpr. The 'exprs' list gets freed if not directly used in the output
6539 * expression tree.
6540 */
6543 Oid inputcollid, List *exprs, bool haveNonConst)
6544{
6545 Node *arrayNode = NULL;
6547 Oid arraytype = get_array_type(coltype);
6548
6549 if (!OidIsValid(arraytype))
6550 return NULL;
6551
6552 /*
6553 * Assemble an array from the list of constants. It seems more profitable
6554 * to build a const array. But in the presence of other nodes, we don't
6555 * have a specific value here and must employ an ArrayExpr instead.
6556 */
6557 if (haveNonConst)
6558 {
6560
6561 /* array_collid will be set by parse_collate.c */
6562 arrayExpr->element_typeid = coltype;
6563 arrayExpr->array_typeid = arraytype;
6564 arrayExpr->multidims = false;
6565 arrayExpr->elements = exprs;
6566 arrayExpr->location = -1;
6567
6568 arrayNode = (Node *) arrayExpr;
6569 }
6570 else
6571 {
6572 int16 typlen;
6573 bool typbyval;
6574 char typalign;
6575 Datum *elems;
6576 bool *nulls;
6577 int i = 0;
6579 int dims[1] = {list_length(exprs)};
6580 int lbs[1] = {1};
6581
6582 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
6583
6584 elems = palloc_array(Datum, list_length(exprs));
6585 nulls = palloc_array(bool, list_length(exprs));
6586 foreach_node(Const, value, exprs)
6587 {
6588 elems[i] = value->constvalue;
6589 nulls[i++] = value->constisnull;
6590 }
6591
6592 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
6593 coltype, typlen, typbyval, typalign);
6596 false, false);
6597
6598 pfree(elems);
6599 pfree(nulls);
6600 list_free(exprs);
6601 }
6602
6603 /* Build the SAOP expression node */
6605 saopexpr->opno = oper;
6606 saopexpr->opfuncid = get_opcode(oper);
6607 saopexpr->hashfuncid = InvalidOid;
6608 saopexpr->negfuncid = InvalidOid;
6609 saopexpr->useOr = true;
6610 saopexpr->inputcollid = inputcollid;
6612 saopexpr->location = -1;
6613
6614 return saopexpr;
6615}
Datum querytree(PG_FUNCTION_ARGS)
Definition _int_bool.c:711
@ ACLCHECK_OK
Definition acl.h:184
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3902
#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:645
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:934
#define bms_is_empty(a)
Definition bitmapset.h:119
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:894
#define Assert(condition)
Definition c.h:1002
int16_t int16
Definition c.h:678
int32_t int32
Definition c.h:679
#define OidIsValid(objectId)
Definition c.h:917
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
static List * simplify_or_arguments(List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceTrue)
Definition clauses.c:4243
static bool rowtype_field_matches(Oid rowtypeid, int fieldnum, Oid expectedtype, int32 expectedtypmod, Oid expectedcollation)
Definition clauses.c:2447
Query * inline_function_in_from(PlannerInfo *root, RangeTblEntry *rte)
Definition clauses.c:5835
static List * add_function_defaults(List *args, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5097
#define ece_all_arguments_const(node)
Definition clauses.c:2691
bool expression_has_grouping_conflict(Node *expr, grouping_eqop_callback get_eqop, void *context)
Definition clauses.c:6318
#define ece_evaluate_expr(node)
Definition clauses.c:2695
bool contain_mutable_functions(Node *clause)
Definition clauses.c:399
#define ece_generic_processing(node)
Definition clauses.c:2682
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:5196
static Node * substitute_actual_parameters_mutator(Node *node, substitute_actual_parameters_context *context)
Definition clauses.c:5691
static bool grouping_check_operand(Node *arg, Oid opno, Oid inputcollid, grouping_walker_ctx *ctx)
Definition clauses.c:6505
static bool ece_function_is_safe(Oid funcid, eval_const_expressions_context *context)
Definition clauses.c:4205
static List * simplify_and_arguments(List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceFalse)
Definition clauses.c:4349
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:4512
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:5322
static List * reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5027
static Node * simplify_aggref(Aggref *aggref, eval_const_expressions_context *context)
Definition clauses.c:4618
static Node * substitute_actual_parameters(Node *expr, int nargs, List *args, int *usecounts)
Definition clauses.c:5678
static Query * substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
Definition clauses.c:6199
bool expr_is_nonnullable(PlannerInfo *root, Expr *expr, NotNullSource source)
Definition clauses.c:4804
static void sql_inline_error_callback(void *arg)
Definition clauses.c:5719
static bool grouping_check_operands(Oid opno, Oid inputcollid, List *args, grouping_walker_ctx *ctx)
Definition clauses.c:6479
static bool contain_non_const_walker(Node *node, void *context)
Definition clauses.c:4189
static bool contain_context_dependent_node(Node *clause)
Definition clauses.c:1210
static void recheck_cast_function_args(List *args, Oid result_type, Oid *proargtypes, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5151
List * expand_function_arguments(List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
Definition clauses.c:4946
bool contain_nonstrict_functions(Node *clause)
Definition clauses.c:1022
static Node * substitute_actual_parameters_in_from_mutator(Node *node, substitute_actual_parameters_in_from_context *context)
Definition clauses.c:6214
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:6039
bool contain_subplans(Node *clause)
Definition clauses.c:359
static Node * simplify_boolean_equality(Oid opno, List *args)
Definition clauses.c:4443
Bitmapset * pull_paramids(Expr *expr)
Definition clauses.c:6259
ScalarArrayOpExpr * make_SAOP_expr(Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, Oid inputcollid, List *exprs, bool haveNonConst)
Definition clauses.c:6543
bool var_is_nonnullable(PlannerInfo *root, Var *var, NotNullSource source)
Definition clauses.c:4660
static bool grouping_conflict_walker(Node *node, grouping_walker_ctx *ctx)
Definition clauses.c:6353
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition clauses.c:2705
static bool pull_paramids_walker(Node *node, Bitmapset **context)
Definition clauses.c:6269
Expr * evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation)
Definition clauses.c:5743
static List * fetch_function_defaults(HeapTuple func_tuple)
Definition clauses.c:5121
bool contain_volatile_functions(Node *clause)
Definition clauses.c:567
Oid(* grouping_eqop_callback)(Var *var, void *context)
Definition clauses.h:34
Oid collid
double cpu_operator_cost
Definition costsize.c:135
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
Definition costsize.c:4923
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
Datum arg
Definition elog.c:1323
ErrorContextCallback * error_context_stack
Definition elog.c:100
#define errcontext
Definition elog.h:200
int internalerrquery(const char *query)
int internalerrposition(int cursorpos)
#define ERROR
Definition elog.h:40
int geterrposition(void)
#define elog(elevel,...)
Definition elog.h:228
int errposition(int cursorpos)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition execExpr.c:143
void FreeExecutorState(EState *estate)
Definition execUtils.c:197
EState * CreateExecutorState(void)
Definition execUtils.c:90
#define GetPerTupleExprContext(estate)
Definition executor.h:665
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:444
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:726
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
#define FmgrHookIsNeeded(fn_oid)
Definition fmgr.h:854
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:2117
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
Definition functions.c:341
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
Definition functions.c:252
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 @173 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
#define NoLock
Definition lockdefs.h:34
RegProcedure get_func_support(Oid funcid)
Definition lsyscache.c:2172
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3223
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2585
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition lsyscache.c:2565
RegProcedure get_opcode(Oid opno)
Definition lsyscache.c:1585
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition lsyscache.c:3190
char func_volatile(Oid funcid)
Definition lsyscache.c:2094
bool equality_ops_are_compatible(Oid opno1, Oid opno2)
Definition lsyscache.c:841
bool op_is_safe_index_member(Oid opno)
Definition lsyscache.c:980
bool get_collation_isdeterministic(Oid colloid)
Definition lsyscache.c:1280
Oid get_array_type(Oid typid)
Definition lsyscache.c:3103
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:1619
void * palloc0(Size size)
Definition mcxt.c:1420
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
#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
Oid exprInputCollation(const Node *expr)
Definition nodeFuncs.c:1092
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:826
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition nodeFuncs.c:641
void fix_opfuncids(Node *node)
Definition nodeFuncs.c:1859
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition nodeFuncs.c:1901
void set_opfuncid(OpExpr *opexpr)
Definition nodeFuncs.c:1890
#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:162
#define copyObject(obj)
Definition nodes.h:230
#define nodeTag(nodeptr)
Definition nodes.h:137
@ CMD_SELECT
Definition nodes.h:273
#define makeNode(_type_)
Definition nodes.h:159
#define castNode(_type_, nodeptr)
Definition nodes.h:180
NotNullSource
Definition optimizer.h:135
@ NOTNULL_SOURCE_HASHTABLE
Definition optimizer.h:137
@ NOTNULL_SOURCE_RELOPT
Definition optimizer.h:136
@ NOTNULL_SOURCE_CATALOG
Definition optimizer.h:138
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
#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:376
@ RTE_FUNCTION
@ RTE_RELATION
#define ACL_EXECUTE
Definition parsenodes.h:83
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
Definition analyze.c:272
#define planner_rt_fetch(rti, root)
Definition pathnodes.h:704
#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:244
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
static void * list_nth(const List *list, int n)
Definition pg_list.h:331
#define linitial(l)
Definition pg_list.h:178
#define list_make3(x1, x2, x3)
Definition pg_list.h:248
#define lsecond(l)
Definition pg_list.h:183
#define foreach_node(type, var, lst)
Definition pg_list.h:528
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition pg_list.h:607
#define lfirst_oid(lc)
Definition pg_list.h:174
#define list_make2(x1, x2)
Definition pg_list.h:246
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:776
List * pg_parse_query(const char *query_string)
Definition postgres.c:617
List * pg_rewrite_query(Query *query)
Definition postgres.c:816
static bool DatumGetBool(Datum X)
Definition postgres.h:100
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 PointerGetDatum(X)
Definition postgres.h:354
#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:1999
@ IS_NOT_FALSE
Definition primnodes.h:1999
@ IS_NOT_UNKNOWN
Definition primnodes.h:1999
@ IS_TRUE
Definition primnodes.h:1999
@ IS_UNKNOWN
Definition primnodes.h:1999
@ IS_FALSE
Definition primnodes.h:1999
@ AND_EXPR
Definition primnodes.h:945
@ OR_EXPR
Definition primnodes.h:945
@ NOT_EXPR
Definition primnodes.h:945
@ PARAM_EXTERN
Definition primnodes.h:385
@ VAR_RETURNING_DEFAULT
Definition primnodes.h:257
@ COERCE_IMPLICIT_CAST
Definition primnodes.h:759
@ COERCE_EXPLICIT_CALL
Definition primnodes.h:757
@ IS_NULL
Definition primnodes.h:1975
@ IS_NOT_NULL
Definition primnodes.h:1975
@ JSCTOR_JSON_ARRAY_QUERY
Definition primnodes.h:1700
tree ctl root
Definition radixtree.h:1857
void * stringToNode(const char *str)
Definition read.c:90
#define RelationGetDescr(relation)
Definition rel.h:542
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:3639
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition setrefs.c:3599
void check_stack_depth(void)
Definition stack_depth.c:96
Oid aggfnoid
Definition primnodes.h:461
BoolExprType boolop
Definition primnodes.h:953
List * args
Definition primnodes.h:954
Expr * arg
Definition primnodes.h:1329
ParseLoc location
Definition primnodes.h:1230
ParseLoc location
Definition primnodes.h:1297
char attnullability
Definition tupdesc.h:80
Oid consttype
Definition primnodes.h:333
MemoryContext es_query_cxt
Definition execnodes.h:747
struct ErrorContextCallback * previous
Definition elog.h:299
Expr xpr
Definition primnodes.h:768
ParseLoc location
Definition primnodes.h:790
Oid funcid
Definition primnodes.h:770
List * args
Definition primnodes.h:788
Definition pg_list.h:54
Definition nodes.h:133
NodeTag type
Definition nodes.h:134
Oid opno
Definition primnodes.h:835
List * args
Definition primnodes.h:853
ParseLoc location
Definition primnodes.h:856
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:214
Bitmapset * notnullattnums
Definition pathnodes.h:1083
List * args
Definition primnodes.h:1431
AttrNumber varattno
Definition primnodes.h:275
int varno
Definition primnodes.h:270
VarReturningType varreturningtype
Definition primnodes.h:298
Index varlevelsup
Definition primnodes.h:295
List * args
Definition primnodes.h:598
Index winref
Definition primnodes.h:604
Expr * aggfilter
Definition primnodes.h:600
ParseLoc location
Definition primnodes.h:612
int ignore_nulls
Definition primnodes.h:610
grouping_eqop_callback get_eqop
Definition clauses.c:110
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
TupleDesc BuildDescFromLists(const List *names, const List *types, const List *typmods, const List *collations)
Definition tupdesc.c:1118
#define ATTNULLABLE_VALID
Definition tupdesc.h:86
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195
bool DomainHasConstraints(Oid type_id, bool *has_volatile)
Definition typcache.c:1497

◆ 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 2695 of file clauses.c.

◆ ece_generic_processing

#define ece_generic_processing (   node)
Value:

Definition at line 2682 of file clauses.c.

◆ MIN_ARRAY_SIZE_FOR_HASHED_SAOP

#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP   9

Definition at line 2531 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 5097 of file clauses.c.

5098{
5099 int nargsprovided = list_length(args);
5100 List *defaults;
5101 int ndelete;
5102
5103 /* Get all the default expressions from the pg_proc tuple */
5105
5106 /* Delete any unused defaults from the list */
5107 ndelete = nargsprovided + list_length(defaults) - pronargs;
5108 if (ndelete < 0)
5109 elog(ERROR, "not enough default arguments");
5110 if (ndelete > 0)
5111 defaults = list_delete_first_n(defaults, ndelete);
5112
5113 /* And form the combined argument list, not modifying the input list */
5114 return list_concat_copy(args, defaults);
5115}

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 2408 of file clauses.c.

2409{
2410 Oid opoid;
2411 Node *temp;
2412
2413 /* Sanity checks: caller is at fault if these fail */
2414 if (!is_opclause(clause) ||
2415 list_length(clause->args) != 2)
2416 elog(ERROR, "cannot commute non-binary-operator clause");
2417
2418 opoid = get_commutator(clause->opno);
2419
2420 if (!OidIsValid(opoid))
2421 elog(ERROR, "could not find commutator for operator %u",
2422 clause->opno);
2423
2424 /*
2425 * modify the clause in-place!
2426 */
2427 clause->opno = opoid;
2428 clause->opfuncid = InvalidOid;
2429 /* opresulttype, opretset, opcollid, inputcollid need not change */
2430
2431 temp = linitial(clause->args);
2432 linitial(clause->args) = lsecond(clause->args);
2433 lsecond(clause->args) = temp;
2434}
Oid get_commutator(Oid opno)
Definition lsyscache.c:1823
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 210 of file clauses.c.

211{
212 return contain_agg_clause_walker(clause, NULL);
213}
static bool contain_agg_clause_walker(Node *node, void *context)
Definition clauses.c:216

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 216 of file clauses.c.

217{
218 if (node == NULL)
219 return false;
220 if (IsA(node, Aggref))
221 {
222 Assert(((Aggref *) node)->agglevelsup == 0);
223 return true; /* abort the tree traversal and return true */
224 }
225 if (IsA(node, GroupingFunc))
226 {
227 Assert(((GroupingFunc *) node)->agglevelsup == 0);
228 return true; /* abort the tree traversal and return true */
229 }
230 Assert(!IsA(node, SubLink));
232}

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 1210 of file clauses.c.

1211{
1212 int flags = 0;
1213
1214 return contain_context_dependent_node_walker(clause, &flags);
1215}
static bool contain_context_dependent_node_walker(Node *node, int *flags)
Definition clauses.c:1220

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 1220 of file clauses.c.

1221{
1222 if (node == NULL)
1223 return false;
1224 if (IsA(node, CaseTestExpr))
1225 return !(*flags & CCDN_CASETESTEXPR_OK);
1226 else if (IsA(node, CaseExpr))
1227 {
1228 CaseExpr *caseexpr = (CaseExpr *) node;
1229
1230 /*
1231 * If this CASE doesn't have a test expression, then it doesn't create
1232 * a context in which CaseTestExprs should appear, so just fall
1233 * through and treat it as a generic expression node.
1234 */
1235 if (caseexpr->arg)
1236 {
1237 int save_flags = *flags;
1238 bool res;
1239
1240 /*
1241 * Note: in principle, we could distinguish the various sub-parts
1242 * of a CASE construct and set the flag bit only for some of them,
1243 * since we are only expecting CaseTestExprs to appear in the
1244 * "expr" subtree of the CaseWhen nodes. But it doesn't really
1245 * seem worth any extra code. If there are any bare CaseTestExprs
1246 * elsewhere in the CASE, something's wrong already.
1247 */
1248 *flags |= CCDN_CASETESTEXPR_OK;
1249 res = expression_tree_walker(node,
1251 flags);
1252 *flags = save_flags;
1253 return res;
1254 }
1255 }
1256 else if (IsA(node, ArrayCoerceExpr))
1257 {
1259 int save_flags;
1260 bool res;
1261
1262 /* Check the array expression */
1263 if (contain_context_dependent_node_walker((Node *) ac->arg, flags))
1264 return true;
1265
1266 /* Check the elemexpr, which is allowed to contain CaseTestExpr */
1267 save_flags = *flags;
1268 *flags |= CCDN_CASETESTEXPR_OK;
1269 res = contain_context_dependent_node_walker((Node *) ac->elemexpr,
1270 flags);
1271 *flags = save_flags;
1272 return res;
1273 }
1275 flags);
1276}
#define CCDN_CASETESTEXPR_OK
Definition clauses.c:1217

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 1168 of file clauses.c.

1169{
1170 return contain_exec_param_walker(clause, param_ids);
1171}
static bool contain_exec_param_walker(Node *node, List *param_ids)
Definition clauses.c:1174

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 1174 of file clauses.c.

1175{
1176 if (node == NULL)
1177 return false;
1178 if (IsA(node, Param))
1179 {
1180 Param *p = (Param *) node;
1181
1182 if (p->paramkind == PARAM_EXEC &&
1184 return true;
1185 }
1187}
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 1294 of file clauses.c.

1295{
1296 return contain_leaked_vars_walker(clause, NULL);
1297}
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition clauses.c:1306

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 1300 of file clauses.c.

1301{
1302 return !get_func_leakproof(func_id);
1303}
bool get_func_leakproof(Oid funcid)
Definition lsyscache.c:2151

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 1306 of file clauses.c.

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

520{
521 /* We assume here that expression_planner() won't scribble on its input */
522 expr = expression_planner(expr);
523
524 /* Now we can search for non-immutable functions */
525 return contain_mutable_functions((Node *) expr);
526}
Expr * expression_planner(Expr *expr)
Definition planner.c:7010

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 405 of file clauses.c.

406{
408}

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 411 of file clauses.c.

412{
413 if (node == NULL)
414 return false;
415 /* Check for mutable functions in node itself */
417 context))
418 return true;
419
420 if (IsA(node, JsonConstructorExpr))
421 {
423 ListCell *lc;
424 bool is_jsonb;
425
426 is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB;
427
428 /*
429 * Check argument_type => json[b] conversions specifically. We still
430 * recurse to check 'args' below, but here we want to specifically
431 * check whether or not the emitted clause would fail to be immutable
432 * because of TimeZone, for example.
433 */
434 foreach(lc, ctor->args)
435 {
436 Oid typid = exprType(lfirst(lc));
437
438 if (is_jsonb ?
439 !to_jsonb_is_immutable(typid) :
440 !to_json_is_immutable(typid))
441 return true;
442 }
443
444 /* Check all subnodes */
445 }
446
447 if (IsA(node, JsonExpr))
448 {
450 Const *cnst;
451
452 if (!IsA(jexpr->path_spec, Const))
453 return true;
454
455 cnst = castNode(Const, jexpr->path_spec);
456
457 Assert(cnst->consttype == JSONPATHOID);
458 if (cnst->constisnull)
459 return false;
460
461 if (jspIsMutable(DatumGetJsonPathP(cnst->constvalue),
462 jexpr->passing_names, jexpr->passing_values))
463 return true;
464 }
465
466 if (IsA(node, SQLValueFunction))
467 {
468 /* all variants of SQLValueFunction are stable */
469 return true;
470 }
471
472 if (IsA(node, NextValueExpr))
473 {
474 /* NextValueExpr is volatile */
475 return true;
476 }
477
478 /*
479 * It should be safe to treat MinMaxExpr as immutable, because it will
480 * depend on a non-cross-type btree comparison function, and those should
481 * always be immutable. Treating XmlExpr as immutable is more dubious,
482 * and treating CoerceToDomain as immutable is outright dangerous. But we
483 * have done so historically, and changing this would probably cause more
484 * problems than it would fix. In practice, if you have a non-immutable
485 * domain constraint you are in for pain anyhow.
486 */
487
488 /* Recurse to check arguments */
489 if (IsA(node, Query))
490 {
491 /* Recurse into subselects */
492 return query_tree_walker((Query *) node,
494 context, 0);
495 }
497 context);
498}
static bool contain_mutable_functions_checker(Oid func_id, void *context)
Definition clauses.c:405
return true
Definition isn.c:130
bool to_json_is_immutable(Oid typoid)
Definition json.c:696
bool to_jsonb_is_immutable(Oid typoid)
Definition jsonb.c:1081
bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
Definition jsonpath.c:1381
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:1648

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 4189 of file clauses.c.

4190{
4191 if (node == NULL)
4192 return false;
4193 if (IsA(node, Const))
4194 return false;
4195 if (IsA(node, List))
4196 return expression_tree_walker(node, contain_non_const_walker, context);
4197 /* Otherwise, abort the tree traversal and return true */
4198 return true;
4199}

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 1022 of file clauses.c.

1023{
1025}
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition clauses.c:1034

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 1028 of file clauses.c.

1029{
1030 return !func_strict(func_id);
1031}
bool func_strict(Oid funcid)
Definition lsyscache.c:2075

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 1034 of file clauses.c.

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

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 365 of file clauses.c.

366{
367 if (node == NULL)
368 return false;
369 if (IsA(node, SubPlan) ||
370 IsA(node, AlternativeSubPlan) ||
371 IsA(node, SubLink))
372 return true; /* abort the tree traversal and return true */
373 return expression_tree_walker(node, contain_subplans_walker, context);
374}

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 567 of file clauses.c.

568{
570}
static bool contain_volatile_functions_walker(Node *node, void *context)
Definition clauses.c:579

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(), create_agg_clause_infos(), distribute_qual_to_rels(), DomainHasConstraints(), 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(), init_notnull_info(), 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 688 of file clauses.c.

689{
690 /* We assume here that expression_planner() won't scribble on its input */
691 expr = expression_planner(expr);
692
693 /* Now we can search for volatile functions */
694 return contain_volatile_functions((Node *) expr);
695}

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 573 of file clauses.c.

574{
576}

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 702 of file clauses.c.

703{
705}
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition clauses.c:715

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 708 of file clauses.c.

709{
710 return (func_id != F_NEXTVAL &&
712}

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 715 of file clauses.c.

716{
717 if (node == NULL)
718 return false;
719 /* Check for volatile functions in node itself */
722 context))
723 return true;
724
725 /*
726 * See notes in contain_mutable_functions_walker about why we treat
727 * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
728 * SQLValueFunction is stable. Hence, none of them are of interest here.
729 * Also, since we're intentionally ignoring nextval(), presumably we
730 * should ignore NextValueExpr.
731 */
732
733 /* Recurse to check arguments */
734 if (IsA(node, Query))
735 {
736 /* Recurse into subselects */
737 return query_tree_walker((Query *) node,
739 context, 0);
740 }
741 return expression_tree_walker(node,
743 context);
744}
static bool contain_volatile_functions_not_nextval_checker(Oid func_id, void *context)
Definition clauses.c:708

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 579 of file clauses.c.

580{
581 if (node == NULL)
582 return false;
583 /* Check for volatile functions in node itself */
585 context))
586 return true;
587
588 if (IsA(node, NextValueExpr))
589 {
590 /* NextValueExpr is volatile */
591 return true;
592 }
593
594 if (IsA(node, RestrictInfo))
595 {
596 RestrictInfo *rinfo = (RestrictInfo *) node;
597
598 /*
599 * For RestrictInfo, check if we've checked the volatility of it
600 * before. If so, we can just use the cached value and not bother
601 * checking it again. Otherwise, check it and cache if whether we
602 * found any volatile functions.
603 */
604 if (rinfo->has_volatile == VOLATILITY_NOVOLATILE)
605 return false;
606 else if (rinfo->has_volatile == VOLATILITY_VOLATILE)
607 return true;
608 else
609 {
610 bool hasvolatile;
611
613 context);
614 if (hasvolatile)
615 rinfo->has_volatile = VOLATILITY_VOLATILE;
616 else
617 rinfo->has_volatile = VOLATILITY_NOVOLATILE;
618
619 return hasvolatile;
620 }
621 }
622
623 if (IsA(node, PathTarget))
624 {
625 PathTarget *target = (PathTarget *) node;
626
627 /*
628 * We also do caching for PathTarget the same as we do above for
629 * RestrictInfos.
630 */
632 return false;
633 else if (target->has_volatile_expr == VOLATILITY_VOLATILE)
634 return true;
635 else
636 {
637 bool hasvolatile;
638
640 context);
641
642 if (hasvolatile)
644 else
646
647 return hasvolatile;
648 }
649 }
650
651 /*
652 * See notes in contain_mutable_functions_walker about why we treat
653 * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
654 * SQLValueFunction is stable. Hence, none of them are of interest here.
655 */
656
657 /* Recurse to check arguments */
658 if (IsA(node, Query))
659 {
660 /* Recurse into subselects */
661 return query_tree_walker((Query *) node,
663 context, 0);
664 }
666 context);
667}
static bool contain_volatile_functions_checker(Oid func_id, void *context)
Definition clauses.c:573
@ VOLATILITY_NOVOLATILE
Definition pathnodes.h:1845
@ VOLATILITY_VOLATILE
Definition pathnodes.h:1844
VolatileFunctionStatus has_volatile_expr
Definition pathnodes.h:1890
List * exprs
Definition pathnodes.h:1878
Expr * clause
Definition pathnodes.h:2901

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 247 of file clauses.c.

248{
249 return contain_windowfuncs(clause);
250}
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 2549 of file clauses.c.

2550{
2552}
static bool convert_saop_to_hashed_saop_walker(Node *node, void *context)
Definition clauses.c:2555

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 2555 of file clauses.c.

2556{
2557 if (node == NULL)
2558 return false;
2559
2560 if (IsA(node, ScalarArrayOpExpr))
2561 {
2562 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node;
2563 Node *leftarg = (Node *) linitial(saop->args);
2564 Node *arrayarg = (Node *) lsecond(saop->args);
2567
2568 if (arrayarg && IsA(arrayarg, Const) &&
2569 !((Const *) arrayarg)->constisnull)
2570 {
2571 if (saop->useOr)
2572 {
2576 {
2577 Datum arrdatum = ((Const *) arrayarg)->constvalue;
2579 int nitems;
2580
2581 /*
2582 * Only fill in the hash functions if the array looks
2583 * large enough for it to be worth hashing instead of
2584 * doing a linear search.
2585 */
2586 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2587
2589 {
2590 /* Looks good. Fill in the hash functions */
2591 saop->hashfuncid = lefthashfunc;
2592 }
2593 return false;
2594 }
2595 }
2596 else /* !saop->useOr */
2597 {
2598 Oid negator = get_negator(saop->opno);
2599
2600 /*
2601 * Check if this is a NOT IN using an operator whose negator
2602 * is hashable. If so we can still build a hash table and
2603 * just ensure the lookup items are not in the hash table.
2604 */
2605 if (OidIsValid(negator) &&
2609 {
2610 Datum arrdatum = ((Const *) arrayarg)->constvalue;
2612 int nitems;
2613
2614 /*
2615 * Only fill in the hash functions if the array looks
2616 * large enough for it to be worth hashing instead of
2617 * doing a linear search.
2618 */
2619 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2620
2622 {
2623 /* Looks good. Fill in the hash functions */
2624 saop->hashfuncid = lefthashfunc;
2625
2626 /*
2627 * Also set the negfuncid. The executor will need
2628 * that to perform hashtable lookups.
2629 */
2630 saop->negfuncid = get_opcode(negator);
2631 }
2632 return false;
2633 }
2634 }
2635 }
2636 }
2637
2639}
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP
Definition clauses.c:2531
#define nitems(x)
Definition indent.h:31
bool get_op_hash_functions_ext(Oid opno, Oid inputtype, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
Definition lsyscache.c:677
Oid get_negator(Oid opno)
Definition lsyscache.c:1847

References ScalarArrayOpExpr::args, ARR_DIMS, ARR_NDIM, ArrayGetNItems(), convert_saop_to_hashed_saop_walker(), DatumGetPointer(), expression_tree_walker, exprType(), fb(), get_negator(), get_op_hash_functions_ext(), get_opcode(), IsA, linitial, 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 4205 of file clauses.c.

4206{
4207 char provolatile = func_volatile(funcid);
4208
4209 /*
4210 * Ordinarily we are only allowed to simplify immutable functions. But for
4211 * purposes of estimation, we consider it okay to simplify functions that
4212 * are merely stable; the risk that the result might change from planning
4213 * time to execution time is worth taking in preference to not being able
4214 * to estimate the value at all.
4215 */
4217 return true;
4218 if (context->estimate && provolatile == PROVOLATILE_STABLE)
4219 return true;
4220 return false;
4221}

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 2516 of file clauses.c.

2517{
2519
2520 if (root)
2521 context.boundParams = root->glob->boundParams; /* bound Params */
2522 else
2523 context.boundParams = NULL;
2524 context.root = root; /* for inlined-function dependencies */
2525 context.active_fns = NIL; /* nothing being recursively simplified */
2526 context.case_val = NULL; /* no CASE being examined */
2527 context.estimate = false; /* safe transformations only */
2528 return eval_const_expressions_mutator(node, &context);
2529}

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 2705 of file clauses.c.

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

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, JSCTOR_JSON_ARRAY_QUERY, 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(), memcpy(), 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(), result, 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 5743 of file clauses.c.

5745{
5746 EState *estate;
5747 ExprState *exprstate;
5748 MemoryContext oldcontext;
5750 bool const_is_null;
5752 bool resultTypByVal;
5753
5754 /*
5755 * To use the executor, we need an EState.
5756 */
5757 estate = CreateExecutorState();
5758
5759 /* We can use the estate's working context to avoid memory leaks. */
5760 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5761
5762 /* Make sure any opfuncids are filled in. */
5763 fix_opfuncids((Node *) expr);
5764
5765 /*
5766 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5767 * because it'd result in recursively invoking eval_const_expressions.)
5768 */
5769 exprstate = ExecInitExpr(expr, NULL);
5770
5771 /*
5772 * And evaluate it.
5773 *
5774 * It is OK to use a default econtext because none of the ExecEvalExpr()
5775 * code used in this situation will use econtext. That might seem
5776 * fortuitous, but it's not so unreasonable --- a constant expression does
5777 * not depend on context, by definition, n'est ce pas?
5778 */
5780 GetPerTupleExprContext(estate),
5781 &const_is_null);
5782
5783 /* Get info needed about result datatype */
5785
5786 /* Get back to outer memory context */
5787 MemoryContextSwitchTo(oldcontext);
5788
5789 /*
5790 * Must copy result out of sub-context used by expression eval.
5791 *
5792 * Also, if it's varlena, forcibly detoast it. This protects us against
5793 * storing TOAST pointers into plans that might outlive the referenced
5794 * data. (makeConst would handle detoasting anyway, but it's worth a few
5795 * extra lines here so that we can do the copy and detoast in one step.)
5796 */
5797 if (!const_is_null)
5798 {
5799 if (resultTypLen == -1)
5801 else
5803 }
5804
5805 /* Release all the junk we just created */
5806 FreeExecutorState(estate);
5807
5808 /*
5809 * Make the constant result node.
5810 */
5811 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5815}

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 5196 of file clauses.c.

5201{
5203 bool has_nonconst_input = false;
5204 bool has_null_input = false;
5205 ListCell *arg;
5207
5208 /*
5209 * Can't simplify if it returns a set.
5210 */
5211 if (funcform->proretset)
5212 return NULL;
5213
5214 /*
5215 * Can't simplify if it returns RECORD. The immediate problem is that it
5216 * will be needing an expected tupdesc which we can't supply here.
5217 *
5218 * In the case where it has OUT parameters, we could build an expected
5219 * tupdesc from those, but there may be other gotchas lurking. In
5220 * particular, if the function were to return NULL, we would produce a
5221 * null constant with no remaining indication of which concrete record
5222 * type it is. For now, seems best to leave the function call unreduced.
5223 */
5224 if (funcform->prorettype == RECORDOID)
5225 return NULL;
5226
5227 /*
5228 * Check for constant inputs and especially constant-NULL inputs.
5229 */
5230 foreach(arg, args)
5231 {
5232 if (IsA(lfirst(arg), Const))
5234 else
5235 has_nonconst_input = true;
5236 }
5237
5238 /*
5239 * If the function is strict and has a constant-NULL input, it will never
5240 * be called at all, so we can replace the call by a NULL constant, even
5241 * if there are other inputs that aren't constant, and even if the
5242 * function is not otherwise immutable.
5243 */
5244 if (funcform->proisstrict && has_null_input)
5245 return (Expr *) makeNullConst(result_type, result_typmod,
5247
5248 /*
5249 * Otherwise, can simplify only if all inputs are constants. (For a
5250 * non-strict function, constant NULL inputs are treated the same as
5251 * constant non-NULL inputs.)
5252 */
5254 return NULL;
5255
5256 /*
5257 * Ordinarily we are only allowed to simplify immutable functions. But for
5258 * purposes of estimation, we consider it okay to simplify functions that
5259 * are merely stable; the risk that the result might change from planning
5260 * time to execution time is worth taking in preference to not being able
5261 * to estimate the value at all.
5262 */
5263 if (funcform->provolatile == PROVOLATILE_IMMUTABLE)
5264 /* okay */ ;
5265 else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE)
5266 /* okay */ ;
5267 else
5268 return NULL;
5269
5270 /*
5271 * OK, looks like we can simplify this operator/function.
5272 *
5273 * Build a new FuncExpr node containing the already-simplified arguments.
5274 */
5276 newexpr->funcid = funcid;
5277 newexpr->funcresulttype = result_type;
5278 newexpr->funcretset = false;
5279 newexpr->funcvariadic = funcvariadic;
5280 newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5281 newexpr->funccollid = result_collid; /* doesn't matter */
5282 newexpr->inputcollid = input_collid;
5283 newexpr->args = args;
5284 newexpr->location = -1;
5285
5286 return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
5288}

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 4946 of file clauses.c.

4948{
4950 Oid *proargtypes = funcform->proargtypes.values;
4951 int pronargs = funcform->pronargs;
4952 bool has_named_args = false;
4953 ListCell *lc;
4954
4955 /*
4956 * If we are asked to match to OUT arguments, then use the proallargtypes
4957 * array (which includes those); otherwise use proargtypes (which
4958 * doesn't). Of course, if proallargtypes is null, we always use
4959 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4960 * considering that we may have nothing to do here, but fortunately the
4961 * common case is include_out_arguments == false.)
4962 */
4964 {
4966 bool isNull;
4967
4970 &isNull);
4971 if (!isNull)
4972 {
4974
4975 pronargs = ARR_DIMS(arr)[0];
4976 if (ARR_NDIM(arr) != 1 ||
4977 pronargs < 0 ||
4978 ARR_HASNULL(arr) ||
4979 ARR_ELEMTYPE(arr) != OIDOID)
4980 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4981 Assert(pronargs >= funcform->pronargs);
4982 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4983 }
4984 }
4985
4986 /* Do we have any named arguments? */
4987 foreach(lc, args)
4988 {
4989 Node *arg = (Node *) lfirst(lc);
4990
4991 if (IsA(arg, NamedArgExpr))
4992 {
4993 has_named_args = true;
4994 break;
4995 }
4996 }
4997
4998 /* If so, we must apply reorder_function_arguments */
4999 if (has_named_args)
5000 {
5002 /* Recheck argument types and add casts if needed */
5003 recheck_cast_function_args(args, result_type,
5005 func_tuple);
5006 }
5007 else if (list_length(args) < pronargs)
5008 {
5009 /* No named args, but we seem to be short some defaults */
5011 /* Recheck argument types and add casts if needed */
5012 recheck_cast_function_args(args, result_type,
5014 func_tuple);
5015 }
5016
5017 return args;
5018}

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 4804 of file clauses.c.

4805{
4806 /* since this function recurses, it could be driven to stack overflow */
4808
4809 switch (nodeTag(expr))
4810 {
4811 case T_Var:
4812 {
4813 if (root)
4814 return var_is_nonnullable(root, (Var *) expr, source);
4815 }
4816 break;
4817 case T_Const:
4818 return !((Const *) expr)->constisnull;
4819 case T_CoalesceExpr:
4820 {
4821 /*
4822 * A CoalesceExpr returns NULL if and only if all its
4823 * arguments are NULL. Therefore, we can determine that a
4824 * CoalesceExpr cannot be NULL if at least one of its
4825 * arguments can be proven non-nullable.
4826 */
4828
4830 {
4832 return true;
4833 }
4834 }
4835 break;
4836 case T_MinMaxExpr:
4837 {
4838 /*
4839 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4840 * its arguments evaluate to NULL.
4841 */
4842 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4843
4845 {
4847 return true;
4848 }
4849 }
4850 break;
4851 case T_CaseExpr:
4852 {
4853 /*
4854 * A CASE expression is non-nullable if all branch results are
4855 * non-nullable. We must also verify that the default result
4856 * (ELSE) exists and is non-nullable.
4857 */
4858 CaseExpr *caseexpr = (CaseExpr *) expr;
4859
4860 /* The default result must be present and non-nullable */
4861 if (caseexpr->defresult == NULL ||
4862 !expr_is_nonnullable(root, caseexpr->defresult, source))
4863 return false;
4864
4865 /* All branch results must be non-nullable */
4867 {
4868 if (!expr_is_nonnullable(root, casewhen->result, source))
4869 return false;
4870 }
4871
4872 return true;
4873 }
4874 break;
4875 case T_ArrayExpr:
4876 {
4877 /*
4878 * An ARRAY[] expression always returns a valid Array object,
4879 * even if it is empty (ARRAY[]) or contains NULLs
4880 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4881 */
4882 return true;
4883 }
4884 case T_NullTest:
4885 {
4886 /*
4887 * An IS NULL / IS NOT NULL expression always returns a
4888 * boolean value. It never returns SQL NULL.
4889 */
4890 return true;
4891 }
4892 case T_BooleanTest:
4893 {
4894 /*
4895 * A BooleanTest expression always evaluates to a boolean
4896 * value. It never returns SQL NULL.
4897 */
4898 return true;
4899 }
4900 case T_DistinctExpr:
4901 {
4902 /*
4903 * IS DISTINCT FROM never returns NULL, effectively acting as
4904 * though NULL were a normal data value.
4905 */
4906 return true;
4907 }
4908 case T_RelabelType:
4909 {
4910 /*
4911 * RelabelType does not change the nullability of the data.
4912 * The result is non-nullable if and only if the argument is
4913 * non-nullable.
4914 */
4915 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4916 source);
4917 }
4918 default:
4919 break;
4920 }
4921
4922 return false;
4923}

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_has_grouping_conflict()

bool expression_has_grouping_conflict ( Node expr,
grouping_eqop_callback  get_eqop,
void context 
)

Definition at line 6318 of file clauses.c.

6321{
6323
6324 if (expr == NULL)
6325 return false;
6326
6327 ctx.get_eqop = get_eqop;
6328 ctx.cb_context = context;
6329
6330 return grouping_conflict_walker(expr, &ctx);
6331}

References grouping_walker_ctx::cb_context, fb(), grouping_walker_ctx::get_eqop, and grouping_conflict_walker().

Referenced by find_having_conflicts(), and qual_is_pushdown_safe().

◆ expression_returns_set_rows()

double expression_returns_set_rows ( PlannerInfo root,
Node clause 
)

Definition at line 318 of file clauses.c.

319{
320 if (clause == NULL)
321 return 1.0;
322 if (IsA(clause, FuncExpr))
323 {
324 FuncExpr *expr = (FuncExpr *) clause;
325
326 if (expr->funcretset)
327 return clamp_row_est(get_function_rows(root, expr->funcid, clause));
328 }
329 if (IsA(clause, OpExpr))
330 {
331 OpExpr *expr = (OpExpr *) clause;
332
333 if (expr->opretset)
334 {
335 set_opfuncid(expr);
336 return clamp_row_est(get_function_rows(root, expr->opfuncid, clause));
337 }
338 }
339 return 1.0;
340}
double clamp_row_est(double nrows)
Definition costsize.c:215
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition plancat.c:2419

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 5121 of file clauses.c.

5122{
5123 List *defaults;
5125 char *str;
5126
5130 defaults = castNode(List, stringToNode(str));
5131 pfree(str);
5132 return defaults;
5133}

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 2013 of file clauses.c.

2014{
2015 if (node == NULL)
2016 return NULL;
2017 if (IsA(node, NullTest))
2018 {
2019 /* check for var IS NULL */
2020 NullTest *expr = (NullTest *) node;
2021
2022 if (expr->nulltesttype == IS_NULL && !expr->argisrow)
2023 {
2024 Var *var = (Var *) expr->arg;
2025
2026 if (var && IsA(var, Var) &&
2027 var->varlevelsup == 0)
2028 return var;
2029 }
2030 }
2031 else if (IsA(node, BooleanTest))
2032 {
2033 /* var IS UNKNOWN is equivalent to var IS NULL */
2034 BooleanTest *expr = (BooleanTest *) node;
2035
2036 if (expr->booltesttype == IS_UNKNOWN)
2037 {
2038 Var *var = (Var *) expr->arg;
2039
2040 if (var && IsA(var, Var) &&
2041 var->varlevelsup == 0)
2042 return var;
2043 }
2044 }
2045 return NULL;
2046}
BoolTestType booltesttype
Definition primnodes.h:2006
NullTestType nulltesttype
Definition primnodes.h:1982
Expr * arg
Definition primnodes.h:1981

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 1952 of file clauses.c.

1953{
1954 List *result = NIL;
1955 Var *var;
1956 ListCell *l;
1957
1958 if (node == NULL)
1959 return NIL;
1960 /* Check single-clause cases using subroutine */
1961 var = find_forced_null_var(node);
1962 if (var)
1963 {
1965 var->varno,
1967 }
1968 /* Otherwise, handle AND-conditions */
1969 else if (IsA(node, List))
1970 {
1971 /*
1972 * At top level, we are examining an implicit-AND list: if any of the
1973 * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
1974 */
1975 foreach(l, (List *) node)
1976 {
1979 }
1980 }
1981 else if (IsA(node, BoolExpr))
1982 {
1983 BoolExpr *expr = (BoolExpr *) node;
1984
1985 /*
1986 * We don't bother considering the OR case, because it's fairly
1987 * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
1988 * the NOT case isn't worth expending code on.
1989 */
1990 if (expr->boolop == AND_EXPR)
1991 {
1992 /* At top level we can just recurse (to the List case) */
1994 }
1995 }
1996 return result;
1997}
List * find_forced_null_vars(Node *node)
Definition clauses.c:1952
Var * find_forced_null_var(Node *node)
Definition clauses.c:2013
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, result, 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 1492 of file clauses.c.

1493{
1494 return find_nonnullable_rels_walker(clause, true);
1495}
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition clauses.c:1498

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 1498 of file clauses.c.

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

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, result, ROWCOMPARE_SUBLINK, set_opfuncid(), 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 1743 of file clauses.c.

1744{
1745 return find_nonnullable_vars_walker(clause, true);
1746}
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition clauses.c:1749

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 1749 of file clauses.c.

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

2206{
2207 if (jtnode == NULL)
2208 return;
2209 if (IsA(jtnode, RangeTblRef))
2210 {
2211 /* Leaf node: nothing to do */
2212 return;
2213 }
2214 else if (IsA(jtnode, FromExpr))
2215 {
2216 FromExpr *f = (FromExpr *) jtnode;
2217
2218 /* All elements of the FROM list are allowable */
2221 /* ... and its WHERE quals are too */
2222 if (f->quals)
2223 *safe_quals = lappend(*safe_quals, f->quals);
2224 }
2225 else if (IsA(jtnode, JoinExpr))
2226 {
2227 JoinExpr *j = (JoinExpr *) jtnode;
2228
2229 switch (j->jointype)
2230 {
2231 case JOIN_INNER:
2232 /* visit both children */
2235 /* and grab the ON quals too */
2236 if (j->quals)
2237 *safe_quals = lappend(*safe_quals, j->quals);
2238 break;
2239
2240 case JOIN_LEFT:
2241 case JOIN_SEMI:
2242 case JOIN_ANTI:
2243
2244 /*
2245 * Only the left input is possibly non-nullable; furthermore,
2246 * the quals of this join don't constrain the left input.
2247 * Note: we probably can't see SEMI or ANTI joins at this
2248 * point, but if we do, we can treat them like LEFT joins.
2249 */
2251 break;
2252
2253 case JOIN_RIGHT:
2254 /* Reverse of the above case */
2256 break;
2257
2258 case JOIN_FULL:
2259 /* Neither side is non-nullable, so stop descending */
2260 break;
2261
2262 default:
2263 elog(ERROR, "unrecognized join type: %d",
2264 (int) j->jointype);
2265 break;
2266 }
2267 }
2268 else
2269 elog(ERROR, "unrecognized node type: %d",
2270 (int) nodeTag(jtnode));
2271}
static void find_subquery_safe_quals(Node *jtnode, List **safe_quals)
Definition clauses.c:2205
if(enc< 0)
int j
Definition isn.c:78
@ JOIN_SEMI
Definition nodes.h:315
@ JOIN_FULL
Definition nodes.h:303
@ JOIN_INNER
Definition nodes.h:301
@ JOIN_RIGHT
Definition nodes.h:304
@ JOIN_LEFT
Definition nodes.h:302
@ JOIN_ANTI
Definition nodes.h:316
List * fromlist
Definition primnodes.h:2379

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 260 of file clauses.c.

261{
263
264 lists->numWindowFuncs = 0;
265 lists->maxWinRef = maxWinRef;
266 lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
268 return lists;
269}
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition clauses.c:272
#define palloc_object(type)
Definition fe_memutils.h:89

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 272 of file clauses.c.

273{
274 if (node == NULL)
275 return false;
276 if (IsA(node, WindowFunc))
277 {
278 WindowFunc *wfunc = (WindowFunc *) node;
279
280 /* winref is unsigned, so one-sided test is OK */
281 if (wfunc->winref > lists->maxWinRef)
282 elog(ERROR, "WindowFunc contains out-of-range winref %u",
283 wfunc->winref);
284
285 lists->windowFuncs[wfunc->winref] =
286 lappend(lists->windowFuncs[wfunc->winref], wfunc);
287 lists->numWindowFuncs++;
288
289 /*
290 * We assume that the parser checked that there are no window
291 * functions in the arguments or filter clause. Hence, we need not
292 * recurse into them. (If either the parser or the planner screws up
293 * on this point, the executor will still catch it; see ExecInitExpr.)
294 */
295 return false;
296 }
297 Assert(!IsA(node, SubLink));
299}

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().

◆ grouping_check_operand()

static bool grouping_check_operand ( Node arg,
Oid  opno,
Oid  inputcollid,
grouping_walker_ctx ctx 
)
static

Definition at line 6505 of file clauses.c.

6507{
6508 Node *node = arg;
6509
6510 while (node && IsA(node, RelabelType))
6511 node = (Node *) ((RelabelType *) node)->arg;
6512
6513 if (node && IsA(node, Var))
6514 {
6515 Var *var = (Var *) node;
6516 Oid grouping_eqop = ctx->get_eqop(var, ctx->cb_context);
6517
6519 {
6520 /* incompatible equality semantics */
6522 return true;
6523 /* nondeterministic collation compared under a different collation */
6524 if (OidIsValid(var->varcollid) &&
6525 !get_collation_isdeterministic(var->varcollid) &&
6526 inputcollid != var->varcollid)
6527 return true;
6528 }
6529 return false; /* direct operand handled; do not recurse */
6530 }
6531
6532 return grouping_conflict_walker(arg, ctx);
6533}

References arg, grouping_walker_ctx::cb_context, equality_ops_are_compatible(), fb(), get_collation_isdeterministic(), grouping_walker_ctx::get_eqop, grouping_conflict_walker(), IsA, and OidIsValid.

Referenced by grouping_check_operands(), and grouping_conflict_walker().

◆ grouping_check_operands()

static bool grouping_check_operands ( Oid  opno,
Oid  inputcollid,
List args,
grouping_walker_ctx ctx 
)
static

Definition at line 6479 of file clauses.c.

6481{
6482 ListCell *lc;
6483
6484 foreach(lc, args)
6485 {
6486 if (grouping_check_operand((Node *) lfirst(lc), opno, inputcollid, ctx))
6487 return true;
6488 }
6489 return false;
6490}

References fb(), grouping_check_operand(), and lfirst.

Referenced by grouping_conflict_walker().

◆ grouping_conflict_walker()

static bool grouping_conflict_walker ( Node node,
grouping_walker_ctx ctx 
)
static

Definition at line 6353 of file clauses.c.

6354{
6355 if (node == NULL)
6356 return false;
6357
6358 if (IsA(node, Var))
6359 {
6360 Var *var = (Var *) node;
6361
6362 /*
6363 * A grouping column reaches here when it was not handled as a direct
6364 * operand by a comparison node above (see the function header). That
6365 * is safe for a deterministic collation, but not for a
6366 * nondeterministic one, where the reference may distinguish values
6367 * the grouping considers equal. A bare boolean qual is safe too:
6368 * boolean is not collatable, so it takes the deterministic path here.
6369 */
6370 if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) &&
6371 OidIsValid(var->varcollid) &&
6372 !get_collation_isdeterministic(var->varcollid))
6373 return true;
6374 return false;
6375 }
6376 else if (IsA(node, OpExpr))
6377 {
6378 OpExpr *opexpr = (OpExpr *) node;
6379
6380 if (op_is_safe_index_member(opexpr->opno))
6381 return grouping_check_operands(opexpr->opno, opexpr->inputcollid,
6382 opexpr->args, ctx);
6383 /* fall through */
6384 }
6385 else if (IsA(node, ScalarArrayOpExpr))
6386 {
6387 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node;
6388
6389 if (op_is_safe_index_member(saop->opno))
6390 return grouping_check_operands(saop->opno, saop->inputcollid,
6391 saop->args, ctx);
6392 /* fall through */
6393 }
6394 else if (IsA(node, RowCompareExpr))
6395 {
6397 ListCell *lc_l;
6398 ListCell *lc_r;
6399 ListCell *lc_o;
6400 ListCell *lc_c;
6401
6402 /* Each column is compared under its own operator and inputcollid. */
6403 forfour(lc_l, rcexpr->largs,
6404 lc_r, rcexpr->rargs,
6405 lc_o, rcexpr->opnos,
6406 lc_c, rcexpr->inputcollids)
6407 {
6408 Oid opno = lfirst_oid(lc_o);
6410
6411 if (grouping_check_operand((Node *) lfirst(lc_l), opno, collid, ctx) ||
6412 grouping_check_operand((Node *) lfirst(lc_r), opno, collid, ctx))
6413 return true;
6414 }
6415 return false;
6416 }
6417 else if (IsA(node, CaseExpr) && ((CaseExpr *) node)->arg != NULL)
6418 {
6419 CaseExpr *cexpr = (CaseExpr *) node;
6420 Node *arg = (Node *) cexpr->arg;
6421
6422 /* Look through RelabelType to find a direct Var arg. */
6423 while (arg && IsA(arg, RelabelType))
6424 arg = (Node *) ((RelabelType *) arg)->arg;
6425
6426 if (arg && IsA(arg, Var))
6427 {
6428 Var *var = (Var *) arg;
6429
6430 /*
6431 * The arg is a grouping column compared by every WHEN. For a
6432 * nondeterministic collation, reject if any WHEN applies a
6433 * different collation.
6434 */
6435 if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) &&
6436 OidIsValid(var->varcollid) &&
6437 !get_collation_isdeterministic(var->varcollid))
6438 {
6439 foreach_node(CaseWhen, cw, cexpr->args)
6440 {
6441 Oid collid = exprInputCollation((Node *) cw->expr);
6442
6443 if (OidIsValid(collid) && collid != var->varcollid)
6444 return true;
6445 }
6446 }
6447 }
6448 else if (grouping_conflict_walker((Node *) cexpr->arg, ctx))
6449 {
6450 /* arg is a complex expression; walked as a non-operand */
6451 return true;
6452 }
6453
6454 /*
6455 * Walk the WHEN conditions, their results, and the default result as
6456 * non-operands. The WHEN conditions hold a CaseTestExpr in place of
6457 * the arg, so they contribute no grouping operand of their own, but
6458 * the condition expression or the substitution result may reference
6459 * another grouping column.
6460 */
6461 foreach_node(CaseWhen, cw, cexpr->args)
6462 {
6463 if (grouping_conflict_walker((Node *) cw->expr, ctx) ||
6464 grouping_conflict_walker((Node *) cw->result, ctx))
6465 return true;
6466 }
6467 return grouping_conflict_walker((Node *) cexpr->defresult, ctx);
6468 }
6469
6471}

References arg, CaseExpr::arg, OpExpr::args, ScalarArrayOpExpr::args, CaseExpr::args, grouping_walker_ctx::cb_context, collid, CaseExpr::defresult, expression_tree_walker, exprInputCollation(), fb(), foreach_node, forfour, get_collation_isdeterministic(), grouping_walker_ctx::get_eqop, grouping_check_operand(), grouping_check_operands(), grouping_conflict_walker(), IsA, lfirst, lfirst_oid, OidIsValid, op_is_safe_index_member(), OpExpr::opno, and ScalarArrayOpExpr::opno.

Referenced by expression_has_grouping_conflict(), grouping_check_operand(), and grouping_conflict_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 5322 of file clauses.c.

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

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 5835 of file clauses.c.

5836{
5837 RangeTblFunction *rtfunc;
5838 FuncExpr *fexpr;
5839 Oid func_oid;
5844 Datum tmp;
5845 char *src;
5846 inline_error_callback_arg callback_arg;
5848 Query *querytree = NULL;
5849
5850 Assert(rte->rtekind == RTE_FUNCTION);
5851
5852 /*
5853 * Guard against infinite recursion during expansion by checking for stack
5854 * overflow. (There's no need to do more.)
5855 */
5857
5858 /* Fail if the RTE has ORDINALITY - we don't implement that here. */
5859 if (rte->funcordinality)
5860 return NULL;
5861
5862 /* Fail if RTE isn't a single, simple FuncExpr */
5863 if (list_length(rte->functions) != 1)
5864 return NULL;
5865 rtfunc = (RangeTblFunction *) linitial(rte->functions);
5866
5867 if (!IsA(rtfunc->funcexpr, FuncExpr))
5868 return NULL;
5869 fexpr = (FuncExpr *) rtfunc->funcexpr;
5870
5871 func_oid = fexpr->funcid;
5872
5873 /*
5874 * Refuse to inline if the arguments contain any volatile functions or
5875 * sub-selects. Volatile functions are rejected because inlining may
5876 * result in the arguments being evaluated multiple times, risking a
5877 * change in behavior. Sub-selects are rejected partly for implementation
5878 * reasons (pushing them down another level might change their behavior)
5879 * and partly because they're likely to be expensive and so multiple
5880 * evaluation would be bad.
5881 */
5882 if (contain_volatile_functions((Node *) fexpr->args) ||
5883 contain_subplans((Node *) fexpr->args))
5884 return NULL;
5885
5886 /* Check permission to call function (fail later, if not) */
5888 return NULL;
5889
5890 /* Check whether a plugin wants to hook function entry/exit */
5892 return NULL;
5893
5894 /*
5895 * OK, let's take a look at the function's pg_proc entry.
5896 */
5899 elog(ERROR, "cache lookup failed for function %u", func_oid);
5901
5902 /*
5903 * If the function SETs any configuration parameters, inlining would cause
5904 * us to miss making those changes.
5905 */
5907 {
5909 return NULL;
5910 }
5911
5912 /*
5913 * Make a temporary memory context, so that we don't leak all the stuff
5914 * that parsing and rewriting might create. If we succeed, we'll copy
5915 * just the finished query tree back up to the caller's context.
5916 */
5918 "inline_function_in_from",
5921
5922 /* Fetch the function body */
5924 src = TextDatumGetCString(tmp);
5925
5926 /*
5927 * If the function has an attached support function that can handle
5928 * SupportRequestInlineInFrom, then attempt to inline with that.
5929 */
5930 if (funcform->prosupport)
5931 {
5933
5935 req.root = root;
5936 req.rtfunc = rtfunc;
5937 req.proc = func_tuple;
5938
5939 querytree = (Query *)
5941 PointerGetDatum(&req)));
5942 }
5943
5944 /*
5945 * Setup error traceback support for ereport(). This is so that we can
5946 * finger the function that bad information came from. We don't install
5947 * this while running the support function, since it'd be likely to do the
5948 * wrong thing: any parse errors reported during that are very likely not
5949 * against the raw function source text.
5950 */
5951 callback_arg.proname = NameStr(funcform->proname);
5952 callback_arg.prosrc = src;
5953
5955 sqlerrcontext.arg = &callback_arg;
5958
5959 /*
5960 * If SupportRequestInlineInFrom didn't work, try our built-in inlining
5961 * mechanism.
5962 */
5963 if (!querytree)
5965 func_tuple, funcform, src);
5966
5967 if (!querytree)
5968 goto fail; /* no luck there either, fail */
5969
5970 /*
5971 * The result had better be a SELECT Query.
5972 */
5974 Assert(querytree->commandType == CMD_SELECT);
5975
5976 /*
5977 * Looks good --- substitute parameters into the query.
5978 */
5980 funcform->pronargs,
5981 fexpr->args);
5982
5983 /*
5984 * Copy the modified query out of the temporary memory context, and clean
5985 * up.
5986 */
5988
5990
5994
5995 /*
5996 * We don't have to fix collations here because the upper query is already
5997 * parsed, ie, the collations in the RTE are what count.
5998 */
5999
6000 /*
6001 * Since there is now no trace of the function in the plan tree, we must
6002 * explicitly record the plan's dependency on the function.
6003 */
6005
6006 /*
6007 * We must also notice if the inserted query adds a dependency on the
6008 * calling role due to RLS quals.
6009 */
6010 if (querytree->hasRowSecurity)
6011 root->glob->dependsOnRole = true;
6012
6013 return querytree;
6014
6015 /* Here if func is not inlinable: release temp memory and return NULL */
6016fail:
6021
6022 return NULL;
6023}

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 6039 of file clauses.c.

6045{
6046 Datum sqlbody;
6047 bool isNull;
6051 TupleDesc rettupdesc;
6052
6053 /*
6054 * The function must be declared to return a set, else inlining would
6055 * change the results if the contained SELECT didn't return exactly one
6056 * row.
6057 */
6058 if (!fexpr->funcretset)
6059 return NULL;
6060
6061 /*
6062 * Forget it if the function is not SQL-language or has other showstopper
6063 * properties. In particular it mustn't be declared STRICT, since we
6064 * couldn't enforce that. It also mustn't be VOLATILE, because that is
6065 * supposed to cause it to be executed with its own snapshot, rather than
6066 * sharing the snapshot of the calling query. We also disallow returning
6067 * SETOF VOID, because inlining would result in exposing the actual result
6068 * of the function's last SELECT, which should not happen in that case.
6069 * (Rechecking prokind, proretset, and pronargs is just paranoia.)
6070 */
6071 if (funcform->prolang != SQLlanguageId ||
6072 funcform->prokind != PROKIND_FUNCTION ||
6073 funcform->proisstrict ||
6074 funcform->provolatile == PROVOLATILE_VOLATILE ||
6075 funcform->prorettype == VOIDOID ||
6076 funcform->prosecdef ||
6077 !funcform->proretset ||
6078 list_length(fexpr->args) != funcform->pronargs)
6079 return NULL;
6080
6081 /* If we have prosqlbody, pay attention to that not prosrc */
6083 func_tuple,
6085 &isNull);
6086 if (!isNull)
6087 {
6088 Node *n;
6089
6091 if (IsA(n, List))
6093 else
6095 if (list_length(querytree_list) != 1)
6096 return NULL;
6098
6099 /* Acquire necessary locks, then apply rewriter. */
6100 AcquireRewriteLocks(querytree, true, false);
6102 if (list_length(querytree_list) != 1)
6103 return NULL;
6105 }
6106 else
6107 {
6110
6111 /*
6112 * Set up to handle parameters while parsing the function body. We
6113 * can use the FuncExpr just created as the input for
6114 * prepare_sql_fn_parse_info.
6115 */
6117 (Node *) fexpr,
6118 fexpr->inputcollid);
6119
6120 /*
6121 * Parse, analyze, and rewrite (unlike inline_function(), we can't
6122 * skip rewriting here). We can fail as soon as we find more than one
6123 * query, though.
6124 */
6127 return NULL;
6128
6130 src,
6132 pinfo, NULL);
6133 if (list_length(querytree_list) != 1)
6134 return NULL;
6136 }
6137
6138 /*
6139 * Also resolve the actual function result tupdesc, if composite. If we
6140 * have a coldeflist, believe that; otherwise use get_expr_result_type.
6141 * (This logic should match ExecInitFunctionScan.)
6142 */
6143 if (rtfunc->funccolnames != NIL)
6144 {
6146 rettupdesc = BuildDescFromLists(rtfunc->funccolnames,
6147 rtfunc->funccoltypes,
6148 rtfunc->funccoltypmods,
6149 rtfunc->funccolcollations);
6150 }
6151 else
6152 functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc);
6153
6154 /*
6155 * The single command must be a plain SELECT.
6156 */
6157 if (!IsA(querytree, Query) ||
6158 querytree->commandType != CMD_SELECT)
6159 return NULL;
6160
6161 /*
6162 * Make sure the function (still) returns what it's declared to. This
6163 * will raise an error if wrong, but that's okay since the function would
6164 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
6165 * coercions if needed to make the tlist expression(s) match the declared
6166 * type of the function. We also ask it to insert dummy NULL columns for
6167 * any dropped columns in rettupdesc, so that the elements of the modified
6168 * tlist match up to the attribute numbers.
6169 *
6170 * If the function returns a composite type, don't inline unless the check
6171 * shows it's returning a whole tuple result; otherwise what it's
6172 * returning is a single composite column which is not what we need.
6173 */
6175 fexpr->funcresulttype, rettupdesc,
6176 funcform->prokind,
6177 true) &&
6181 return NULL; /* reject not-whole-tuple-result cases */
6182
6183 /*
6184 * check_sql_fn_retval might've inserted a projection step, but that's
6185 * fine; just make sure we use the upper Query.
6186 */
6188
6189 return querytree;
6190}

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 782 of file clauses.c.

783{
786 ListCell *l;
787
788 /*
789 * Even if the original querytree contained nothing unsafe, we need to
790 * search the expression if we have generated any PARAM_EXEC Params while
791 * planning, because those are parallel-restricted and there might be one
792 * in this expression. But otherwise we don't need to look.
793 */
794 if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
795 root->glob->paramExecTypes == NIL)
796 return true;
797 /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
800 context.safe_param_ids = NIL;
801
802 /*
803 * The params that refer to the same or parent query level are considered
804 * parallel-safe. The idea is that we compute such params at Gather or
805 * Gather Merge node and pass their value to workers.
806 */
807 for (proot = root; proot != NULL; proot = proot->parent_root)
808 {
809 foreach(l, proot->init_plans)
810 {
812
813 context.safe_param_ids = list_concat(context.safe_param_ids,
814 initsubplan->setParam);
815 }
816 }
817
818 return !max_parallel_hazard_walker(node, &context);
819}
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition clauses.c:858
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 2349 of file clauses.c.

2350{
2351 /*
2352 * We could implement this check in one recursive scan. But since the
2353 * check for volatile functions is both moderately expensive and unlikely
2354 * to fail, it seems better to look for Vars first and only check for
2355 * volatile functions if we find no Vars.
2356 */
2357 if (!contain_var_clause(clause) &&
2359 return true;
2360 return false;
2361}

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 2369 of file clauses.c.

2370{
2371 if (bms_is_empty(relids) &&
2373 return true;
2374 return false;
2375}

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 2287 of file clauses.c.

2288{
2289 Node *rightop;
2290
2291 /* The contained operator must be strict. */
2292 set_sa_opfuncid(expr);
2293 if (!func_strict(expr->opfuncid))
2294 return false;
2295 /* If ANY and falseOK, that's all we need to check. */
2296 if (expr->useOr && falseOK)
2297 return true;
2298 /* Else, we have to see if the array is provably non-empty. */
2299 Assert(list_length(expr->args) == 2);
2300 rightop = (Node *) lsecond(expr->args);
2301 if (rightop && IsA(rightop, Const))
2302 {
2303 Datum arraydatum = ((Const *) rightop)->constvalue;
2304 bool arrayisnull = ((Const *) rightop)->constisnull;
2306 int nitems;
2307
2308 if (arrayisnull)
2309 return false;
2312 if (nitems > 0)
2313 return true;
2314 }
2315 else if (rightop && IsA(rightop, ArrayExpr))
2316 {
2317 ArrayExpr *arrayexpr = (ArrayExpr *) rightop;
2318
2319 if (arrayexpr->elements != NIL && !arrayexpr->multidims)
2320 return true;
2321 }
2322 return false;
2323}

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 6543 of file clauses.c.

6545{
6546 Node *arrayNode = NULL;
6548 Oid arraytype = get_array_type(coltype);
6549
6550 if (!OidIsValid(arraytype))
6551 return NULL;
6552
6553 /*
6554 * Assemble an array from the list of constants. It seems more profitable
6555 * to build a const array. But in the presence of other nodes, we don't
6556 * have a specific value here and must employ an ArrayExpr instead.
6557 */
6558 if (haveNonConst)
6559 {
6561
6562 /* array_collid will be set by parse_collate.c */
6563 arrayExpr->element_typeid = coltype;
6564 arrayExpr->array_typeid = arraytype;
6565 arrayExpr->multidims = false;
6566 arrayExpr->elements = exprs;
6567 arrayExpr->location = -1;
6568
6569 arrayNode = (Node *) arrayExpr;
6570 }
6571 else
6572 {
6573 int16 typlen;
6574 bool typbyval;
6575 char typalign;
6576 Datum *elems;
6577 bool *nulls;
6578 int i = 0;
6580 int dims[1] = {list_length(exprs)};
6581 int lbs[1] = {1};
6582
6583 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
6584
6585 elems = palloc_array(Datum, list_length(exprs));
6586 nulls = palloc_array(bool, list_length(exprs));
6587 foreach_node(Const, value, exprs)
6588 {
6589 elems[i] = value->constvalue;
6590 nulls[i++] = value->constisnull;
6591 }
6592
6593 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
6594 coltype, typlen, typbyval, typalign);
6597 false, false);
6598
6599 pfree(elems);
6600 pfree(nulls);
6601 list_free(exprs);
6602 }
6603
6604 /* Build the SAOP expression node */
6606 saopexpr->opno = oper;
6607 saopexpr->opfuncid = get_opcode(oper);
6608 saopexpr->hashfuncid = InvalidOid;
6609 saopexpr->negfuncid = InvalidOid;
6610 saopexpr->useOr = true;
6611 saopexpr->inputcollid = inputcollid;
6613 saopexpr->location = -1;
6614
6615 return saopexpr;
6616}

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 851 of file clauses.c.

852{
854 (max_parallel_hazard_context *) context);
855}
static bool max_parallel_hazard_test(char proparallel, max_parallel_hazard_context *context)
Definition clauses.c:823
char func_parallel(Oid funcid)
Definition lsyscache.c:2113

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 823 of file clauses.c.

824{
825 switch (proparallel)
826 {
827 case PROPARALLEL_SAFE:
828 /* nothing to see here, move along */
829 break;
831 /* increase max_hazard to RESTRICTED */
833 context->max_hazard = proparallel;
834 /* done if we are not expecting any unsafe functions */
835 if (context->max_interesting == proparallel)
836 return true;
837 break;
839 context->max_hazard = proparallel;
840 /* we're always done at the first unsafe construct */
841 return true;
842 default:
843 elog(ERROR, "unrecognized proparallel value \"%c\"", proparallel);
844 break;
845 }
846 return false;
847}

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 858 of file clauses.c.

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

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 2391 of file clauses.c.

2392{
2393 int result;
2394 Relids varnos = pull_varnos(root, clause);
2395
2396 varnos = bms_del_members(varnos, root->outer_join_rels);
2397 result = bms_num_members(varnos);
2398 bms_free(varnos);
2399 return result;
2400}
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:1280
void bms_free(Bitmapset *a)
Definition bitmapset.c:240
int bms_num_members(const Bitmapset *a)
Definition bitmapset.c:879
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition var.c:114

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

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

◆ pull_paramids()

Bitmapset * pull_paramids ( Expr expr)

Definition at line 6259 of file clauses.c.

6260{
6262
6263 (void) pull_paramids_walker((Node *) expr, &result);
6264
6265 return result;
6266}

References fb(), pull_paramids_walker(), and result.

Referenced by create_memoize_plan().

◆ pull_paramids_walker()

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

Definition at line 6269 of file clauses.c.

6270{
6271 if (node == NULL)
6272 return false;
6273 if (IsA(node, Param))
6274 {
6275 Param *param = (Param *) node;
6276
6277 *context = bms_add_member(*context, param->paramid);
6278 return false;
6279 }
6280 return expression_tree_walker(node, pull_paramids_walker, context);
6281}

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 2067 of file clauses.c.

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

5154{
5156 int nargs;
5159 Oid rettype;
5160 ListCell *lc;
5161
5162 if (list_length(args) > FUNC_MAX_ARGS)
5163 elog(ERROR, "too many function arguments");
5164 nargs = 0;
5165 foreach(lc, args)
5166 {
5167 actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));
5168 }
5169 Assert(nargs == pronargs);
5173 nargs,
5174 funcform->prorettype,
5175 false);
5176 /* let's just check we got the same answer as the parser did ... */
5177 if (rettype != result_type)
5178 elog(ERROR, "function's resolved result type changed during planning");
5179
5180 /* perform any necessary typecasting of arguments */
5182}

References Assert, elog, enforce_generic_type_consistency(), ERROR, exprType(), fb(), Form_pg_proc, FUNC_MAX_ARGS, GETSTRUCT(), lfirst, list_length(), make_fn_arguments(), memcpy(), 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 5027 of file clauses.c.

5028{
5030 int nargsprovided = list_length(args);
5032 ListCell *lc;
5033 int i;
5034
5037 elog(ERROR, "too many function arguments");
5038 memset(argarray, 0, pronargs * sizeof(Node *));
5039
5040 /* Deconstruct the argument list into an array indexed by argnumber */
5041 i = 0;
5042 foreach(lc, args)
5043 {
5044 Node *arg = (Node *) lfirst(lc);
5045
5046 if (!IsA(arg, NamedArgExpr))
5047 {
5048 /* positional argument, assumed to precede all named args */
5049 Assert(argarray[i] == NULL);
5050 argarray[i++] = arg;
5051 }
5052 else
5053 {
5055
5056 Assert(na->argnumber >= 0 && na->argnumber < pronargs);
5057 Assert(argarray[na->argnumber] == NULL);
5058 argarray[na->argnumber] = (Node *) na->arg;
5059 }
5060 }
5061
5062 /*
5063 * Fetch default expressions, if needed, and insert into array at proper
5064 * locations (they aren't necessarily consecutive or all used)
5065 */
5066 if (nargsprovided < pronargs)
5067 {
5069
5070 i = pronargs - funcform->pronargdefaults;
5071 foreach(lc, defaults)
5072 {
5073 if (argarray[i] == NULL)
5074 argarray[i] = (Node *) lfirst(lc);
5075 i++;
5076 }
5077 }
5078
5079 /* Now reconstruct the args list in proper order */
5080 args = NIL;
5081 for (i = 0; i < pronargs; i++)
5082 {
5083 Assert(argarray[i] != NULL);
5084 args = lappend(args, argarray[i]);
5085 }
5086
5087 return args;
5088}

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 2447 of file clauses.c.

2450{
2451 TupleDesc tupdesc;
2452 Form_pg_attribute attr;
2453
2454 /* No issue for RECORD, since there is no way to ALTER such a type */
2455 if (rowtypeid == RECORDOID)
2456 return true;
2457 tupdesc = lookup_rowtype_tupdesc_domain(rowtypeid, -1, false);
2459 {
2460 ReleaseTupleDesc(tupdesc);
2461 return false;
2462 }
2463 attr = TupleDescAttr(tupdesc, fieldnum - 1);
2464 if (attr->attisdropped ||
2465 attr->atttypid != expectedtype ||
2466 attr->atttypmod != expectedtypmod ||
2467 attr->attcollation != expectedcollation)
2468 {
2469 ReleaseTupleDesc(tupdesc);
2470 return false;
2471 }
2472 ReleaseTupleDesc(tupdesc);
2473 return true;
2474}
FormData_pg_attribute * Form_pg_attribute
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:240
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition typcache.c:2005

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 4618 of file clauses.c.

4619{
4621
4623 {
4625 Node *newnode;
4626
4627 /*
4628 * Build a SupportRequestSimplifyAggref node to pass to the support
4629 * function.
4630 */
4632 req.root = context->root;
4633 req.aggref = aggref;
4634
4636 PointerGetDatum(&req)));
4637
4638 /*
4639 * We expect the support function to return either a new Node or NULL
4640 * (when simplification isn't possible).
4641 */
4642 Assert(newnode != (Node *) aggref || newnode == NULL);
4643
4644 if (newnode != NULL)
4645 return newnode;
4646 }
4647
4648 return (Node *) aggref;
4649}

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 4349 of file clauses.c.

4352{
4353 List *newargs = NIL;
4355
4356 /* See comments in simplify_or_arguments */
4358 while (unprocessed_args)
4359 {
4361
4363
4364 /* flatten nested ANDs as per above comment */
4365 if (is_andclause(arg))
4366 {
4367 List *subargs = ((BoolExpr *) arg)->args;
4369
4371 /* perhaps-overly-tense code to avoid leaking old lists */
4373 continue;
4374 }
4375
4376 /* If it's not an AND, simplify it */
4378
4379 /*
4380 * It is unlikely but not impossible for simplification of a non-AND
4381 * clause to produce an AND. Recheck, but don't be too tense about it
4382 * since it's not a mainstream case. In particular we don't worry
4383 * about const-simplifying the input twice, nor about list leakage.
4384 */
4385 if (is_andclause(arg))
4386 {
4387 List *subargs = ((BoolExpr *) arg)->args;
4388
4390 continue;
4391 }
4392
4393 /*
4394 * OK, we have a const-simplified non-AND argument. Process it per
4395 * comments above.
4396 */
4397 if (IsA(arg, Const))
4398 {
4399 Const *const_input = (Const *) arg;
4400
4401 if (const_input->constisnull)
4402 *haveNull = true;
4403 else if (!DatumGetBool(const_input->constvalue))
4404 {
4405 *forceFalse = true;
4406
4407 /*
4408 * Once we detect a FALSE result we can just exit the loop
4409 * immediately. However, if we ever add a notion of
4410 * non-removable functions, we'd need to keep scanning.
4411 */
4412 return NIL;
4413 }
4414 /* otherwise, we can drop the constant-true input */
4415 continue;
4416 }
4417
4418 /* else emit the simplified arg into the result list */
4420 }
4421
4422 return newargs;
4423}

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 4443 of file clauses.c.

4444{
4445 Node *leftop;
4446 Node *rightop;
4447
4448 Assert(list_length(args) == 2);
4449 leftop = linitial(args);
4450 rightop = lsecond(args);
4451 if (leftop && IsA(leftop, Const))
4452 {
4453 Assert(!((Const *) leftop)->constisnull);
4454 if (opno == BooleanEqualOperator)
4455 {
4456 if (DatumGetBool(((Const *) leftop)->constvalue))
4457 return rightop; /* true = foo */
4458 else
4459 return negate_clause(rightop); /* false = foo */
4460 }
4461 else
4462 {
4463 if (DatumGetBool(((Const *) leftop)->constvalue))
4464 return negate_clause(rightop); /* true <> foo */
4465 else
4466 return rightop; /* false <> foo */
4467 }
4468 }
4469 if (rightop && IsA(rightop, Const))
4470 {
4472 if (opno == BooleanEqualOperator)
4473 {
4475 return leftop; /* foo = true */
4476 else
4477 return negate_clause(leftop); /* foo = false */
4478 }
4479 else
4480 {
4482 return negate_clause(leftop); /* foo <> true */
4483 else
4484 return leftop; /* foo <> false */
4485 }
4486 }
4487 return NULL;
4488}

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 4512 of file clauses.c.

4516{
4517 List *args = *args_p;
4520 Expr *newexpr;
4521
4522 /*
4523 * We have three strategies for simplification: execute the function to
4524 * deliver a constant result, use a transform function to generate a
4525 * substitute node tree, or expand in-line the body of the function
4526 * definition (which only works for simple SQL-language functions, but
4527 * that is a common case). Each case needs access to the function's
4528 * pg_proc tuple, so fetch it just once.
4529 *
4530 * Note: the allow_non_const flag suppresses both the second and third
4531 * strategies; so if !allow_non_const, simplify_function can only return a
4532 * Const or NULL. Argument-list rewriting happens anyway, though.
4533 */
4536 elog(ERROR, "cache lookup failed for function %u", funcid);
4538
4539 /*
4540 * Process the function arguments, unless the caller did it already.
4541 *
4542 * Here we must deal with named or defaulted arguments, and then
4543 * recursively apply eval_const_expressions to the whole argument list.
4544 */
4545 if (process_args)
4546 {
4547 args = expand_function_arguments(args, false, result_type, func_tuple);
4550 context);
4551 /* Argument processing done, give it back to the caller */
4552 *args_p = args;
4553 }
4554
4555 /* Now attempt simplification of the function call proper. */
4556
4557 newexpr = evaluate_function(funcid, result_type, result_typmod,
4559 args, funcvariadic,
4560 func_tuple, context);
4561
4562 if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport))
4563 {
4564 /*
4565 * Build a SupportRequestSimplify node to pass to the support
4566 * function, pointing to a dummy FuncExpr node containing the
4567 * simplified arg list. We use this approach to present a uniform
4568 * interface to the support function regardless of how the target
4569 * function is actually being invoked.
4570 */
4573
4574 fexpr.xpr.type = T_FuncExpr;
4575 fexpr.funcid = funcid;
4576 fexpr.funcresulttype = result_type;
4577 fexpr.funcretset = func_form->proretset;
4578 fexpr.funcvariadic = funcvariadic;
4579 fexpr.funcformat = COERCE_EXPLICIT_CALL;
4580 fexpr.funccollid = result_collid;
4581 fexpr.inputcollid = input_collid;
4582 fexpr.args = args;
4583 fexpr.location = -1;
4584
4586 req.root = context->root;
4587 req.fcall = &fexpr;
4588
4589 newexpr = (Expr *)
4591 PointerGetDatum(&req)));
4592
4593 /* catch a possible API misunderstanding */
4594 Assert(newexpr != (Expr *) &fexpr);
4595 }
4596
4597 if (!newexpr && allow_non_const)
4598 newexpr = inline_function(funcid, result_type, result_collid,
4600 func_tuple, context);
4601
4603
4604 return newexpr;
4605}

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 4243 of file clauses.c.

4246{
4247 List *newargs = NIL;
4249
4250 /*
4251 * We want to ensure that any OR immediately beneath another OR gets
4252 * flattened into a single OR-list, so as to simplify later reasoning.
4253 *
4254 * To avoid stack overflow from recursion of eval_const_expressions, we
4255 * resort to some tenseness here: we keep a list of not-yet-processed
4256 * inputs, and handle flattening of nested ORs by prepending to the to-do
4257 * list instead of recursing. Now that the parser generates N-argument
4258 * ORs from simple lists, this complexity is probably less necessary than
4259 * it once was, but we might as well keep the logic.
4260 */
4262 while (unprocessed_args)
4263 {
4265
4267
4268 /* flatten nested ORs as per above comment */
4269 if (is_orclause(arg))
4270 {
4271 List *subargs = ((BoolExpr *) arg)->args;
4273
4275 /* perhaps-overly-tense code to avoid leaking old lists */
4277 continue;
4278 }
4279
4280 /* If it's not an OR, simplify it */
4282
4283 /*
4284 * It is unlikely but not impossible for simplification of a non-OR
4285 * clause to produce an OR. Recheck, but don't be too tense about it
4286 * since it's not a mainstream case. In particular we don't worry
4287 * about const-simplifying the input twice, nor about list leakage.
4288 */
4289 if (is_orclause(arg))
4290 {
4291 List *subargs = ((BoolExpr *) arg)->args;
4292
4294 continue;
4295 }
4296
4297 /*
4298 * OK, we have a const-simplified non-OR argument. Process it per
4299 * comments above.
4300 */
4301 if (IsA(arg, Const))
4302 {
4303 Const *const_input = (Const *) arg;
4304
4305 if (const_input->constisnull)
4306 *haveNull = true;
4307 else if (DatumGetBool(const_input->constvalue))
4308 {
4309 *forceTrue = true;
4310
4311 /*
4312 * Once we detect a TRUE result we can just exit the loop
4313 * immediately. However, if we ever add a notion of
4314 * non-removable functions, we'd need to keep scanning.
4315 */
4316 return NIL;
4317 }
4318 /* otherwise, we can drop the constant-false input */
4319 continue;
4320 }
4321
4322 /* else emit the simplified arg into the result list */
4324 }
4325
4326 return newargs;
4327}

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 5719 of file clauses.c.

5720{
5723
5724 /* If it's a syntax error, convert to internal syntax error report */
5726 if (syntaxerrposition > 0)
5727 {
5728 errposition(0);
5730 internalerrquery(callback_arg->prosrc);
5731 }
5732
5733 errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
5734}

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 5678 of file clauses.c.

5680{
5682
5683 context.nargs = nargs;
5684 context.args = args;
5685 context.usecounts = usecounts;
5686
5687 return substitute_actual_parameters_mutator(expr, &context);
5688}

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 6214 of file clauses.c.

6216{
6217 Node *result;
6218
6219 if (node == NULL)
6220 return NULL;
6221 if (IsA(node, Query))
6222 {
6223 context->sublevels_up++;
6224 result = (Node *) query_tree_mutator((Query *) node,
6226 context,
6227 0);
6228 context->sublevels_up--;
6229 return result;
6230 }
6231 if (IsA(node, Param))
6232 {
6233 Param *param = (Param *) node;
6234
6235 if (param->paramkind == PARAM_EXTERN)
6236 {
6237 if (param->paramid <= 0 || param->paramid > context->nargs)
6238 elog(ERROR, "invalid paramid: %d", param->paramid);
6239
6240 /*
6241 * Since the parameter is being inserted into a subquery, we must
6242 * adjust levels.
6243 */
6244 result = copyObject(list_nth(context->args, param->paramid - 1));
6246 return result;
6247 }
6248 }
6249 return expression_tree_mutator(node,
6251 context);
6252}

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, result, 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 5691 of file clauses.c.

5693{
5694 if (node == NULL)
5695 return NULL;
5696 if (IsA(node, Param))
5697 {
5698 Param *param = (Param *) node;
5699
5700 if (param->paramkind != PARAM_EXTERN)
5701 elog(ERROR, "unexpected paramkind: %d", (int) param->paramkind);
5702 if (param->paramid <= 0 || param->paramid > context->nargs)
5703 elog(ERROR, "invalid paramid: %d", param->paramid);
5704
5705 /* Count usage of parameter */
5706 context->usecounts[param->paramid - 1]++;
5707
5708 /* Select the appropriate actual arg and replace the Param with it */
5709 /* We don't need to copy at this time (it'll get done later) */
5710 return list_nth(context->args, param->paramid - 1);
5711 }
5713}

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 4660 of file clauses.c.

4661{
4662 Assert(IsA(var, Var));
4663
4664 /* skip upper-level Vars */
4665 if (var->varlevelsup != 0)
4666 return false;
4667
4668 /* could the Var be nulled by any outer joins or grouping sets? */
4669 if (!bms_is_empty(var->varnullingrels))
4670 return false;
4671
4672 /*
4673 * If the Var has a non-default returning type, it could be NULL
4674 * regardless of any NOT NULL constraint. For example, OLD.col is NULL
4675 * for INSERT, and NEW.col is NULL for DELETE.
4676 */
4678 return false;
4679
4680 /* system columns cannot be NULL */
4681 if (var->varattno < 0)
4682 return true;
4683
4684 /* we don't trust whole-row Vars */
4685 if (var->varattno == 0)
4686 return false;
4687
4688 /* Check if the Var is defined as NOT NULL. */
4689 switch (source)
4690 {
4692 {
4693 /*
4694 * We retrieve the column NOT NULL constraint information from
4695 * the corresponding RelOptInfo.
4696 */
4697 RelOptInfo *rel;
4698 Bitmapset *notnullattnums;
4699
4700 rel = find_base_rel(root, var->varno);
4701 notnullattnums = rel->notnullattnums;
4702
4703 return bms_is_member(var->varattno, notnullattnums);
4704 }
4706 {
4707 /*
4708 * We retrieve the column NOT NULL constraint information from
4709 * the hash table.
4710 */
4712 Bitmapset *notnullattnums;
4713
4714 rte = planner_rt_fetch(var->varno, root);
4715
4716 /* We can only reason about ordinary relations */
4717 if (rte->rtekind != RTE_RELATION)
4718 return false;
4719
4720 /*
4721 * We must skip inheritance parent tables, as some child
4722 * tables may have a NOT NULL constraint for a column while
4723 * others may not. This cannot happen with partitioned
4724 * tables, though.
4725 */
4726 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4727 return false;
4728
4729 notnullattnums = find_relation_notnullatts(root, rte->relid);
4730
4731 return bms_is_member(var->varattno, notnullattnums);
4732 }
4734 {
4735 /*
4736 * We check the attnullability field in the tuple descriptor.
4737 * This is necessary rather than checking the attnotnull field
4738 * from the attribute relation, because attnotnull is also set
4739 * for invalid (NOT VALID) NOT NULL constraints, which do not
4740 * guarantee the absence of NULLs.
4741 */
4743 Relation rel;
4744 CompactAttribute *attr;
4745 bool result;
4746
4747 rte = planner_rt_fetch(var->varno, root);
4748
4749 /* We can only reason about ordinary relations */
4750 if (rte->rtekind != RTE_RELATION)
4751 return false;
4752
4753 /*
4754 * We must skip inheritance parent tables, as some child
4755 * tables may have a NOT NULL constraint for a column while
4756 * others may not. This cannot happen with partitioned
4757 * tables, though.
4758 *
4759 * Note that we need to check if the relation actually has any
4760 * children, as we might not have done that yet.
4761 */
4762 if (rte->inh && has_subclass(rte->relid) &&
4763 rte->relkind != RELKIND_PARTITIONED_TABLE)
4764 return false;
4765
4766 /* We need not lock the relation since it was already locked */
4767 rel = table_open(rte->relid, NoLock);
4769 var->varattno - 1);
4771 table_close(rel, NoLock);
4772
4773 return result;
4774 }
4775 default:
4776 elog(ERROR, "unrecognized NotNullSource: %d",
4777 (int) source);
4778 break;
4779 }
4780
4781 return false;
4782}

References Assert, CompactAttribute::attnullability, ATTNULLABLE_VALID, bms_is_empty, bms_is_member(), elog, ERROR, fb(), find_base_rel(), find_relation_notnullatts(), has_subclass(), IsA, NoLock, NOTNULL_SOURCE_CATALOG, NOTNULL_SOURCE_HASHTABLE, NOTNULL_SOURCE_RELOPT, RelOptInfo::notnullattnums, planner_rt_fetch, RelationGetDescr, result, root, RTE_RELATION, source, table_close(), table_open(), TupleDescCompactAttr(), VAR_RETURNING_DEFAULT, Var::varattno, Var::varlevelsup, Var::varno, and Var::varreturningtype.

Referenced by expr_is_nonnullable().