PostgreSQL Source Code git master
Loading...
Searching...
No Matches
clauses.h File Reference
#include "nodes/pathnodes.h"
Include dependency graph for clauses.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  WindowFuncLists
 

Typedefs

typedef Oid(* grouping_eqop_callback) (Var *var, void *context)
 

Functions

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)
 
char max_parallel_hazard (Query *parse)
 
bool is_parallel_safe (PlannerInfo *root, Node *node)
 
bool contain_nonstrict_functions (Node *clause)
 
bool contain_exec_param (Node *clause, List *param_ids)
 
bool contain_leaked_vars (Node *clause)
 
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)
 
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)
 

Typedef Documentation

◆ grouping_eqop_callback

typedef Oid(* grouping_eqop_callback) (Var *var, void *context)

Definition at line 34 of file clauses.h.

Function Documentation

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)
extern

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}
#define OidIsValid(objectId)
Definition c.h:917
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
Oid get_commutator(Oid opno)
Definition lsyscache.c:1823
static bool is_opclause(const void *clause)
Definition nodeFuncs.h:76
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
#define InvalidOid
unsigned int Oid
static int fb(int x)
Definition nodes.h:133
Oid opno
Definition primnodes.h:835
List * args
Definition primnodes.h:853

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)
extern

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

bool contain_exec_param ( Node clause,
List param_ids 
)
extern

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

bool contain_leaked_vars ( Node clause)
extern

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

bool contain_nonstrict_functions ( Node clause)
extern

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

bool contain_subplans ( Node clause)
extern

◆ contain_window_function()

bool contain_window_function ( Node clause)
extern

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

◆ expression_has_grouping_conflict()

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

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}
static bool grouping_conflict_walker(Node *node, grouping_walker_ctx *ctx)
Definition clauses.c:6353
grouping_eqop_callback get_eqop
Definition clauses.c:110

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 
)
extern

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
void set_opfuncid(OpExpr *opexpr)
Definition nodeFuncs.c:1890
#define IsA(nodeptr, _type_)
Definition nodes.h:162
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition plancat.c:2419
tree ctl root
Definition radixtree.h:1857
Oid funcid
Definition primnodes.h:770

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

◆ find_forced_null_var()

Var * find_forced_null_var ( Node node)
extern

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}
@ IS_UNKNOWN
Definition primnodes.h:1999
@ IS_NULL
Definition primnodes.h:1975
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)
extern

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}
uint32 result
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 lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
@ AND_EXPR
Definition primnodes.h:945
BoolExprType boolop
Definition primnodes.h:953
List * args
Definition primnodes.h:954
Definition pg_list.h:54
AttrNumber varattno
Definition primnodes.h:275
int varno
Definition primnodes.h:270
#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)
extern

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

List * find_nonnullable_vars ( Node clause)
extern

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

WindowFuncLists * find_window_functions ( Node clause,
Index  maxWinRef 
)
extern

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
void * palloc0(Size size)
Definition mcxt.c:1420

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

Referenced by grouping_planner().

◆ inline_function_in_from()

Query * inline_function_in_from ( PlannerInfo root,
RangeTblEntry rte 
)
extern

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}
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 TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:894
#define Assert(condition)
Definition c.h:1002
static Query * substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
Definition clauses.c:6199
static void sql_inline_error_callback(void *arg)
Definition clauses.c:5719
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
bool contain_volatile_functions(Node *clause)
Definition clauses.c:567
ErrorContextCallback * error_context_stack
Definition elog.c:100
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:726
#define FmgrHookIsNeeded(fn_oid)
Definition fmgr.h:854
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)
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
#define copyObject(obj)
Definition nodes.h:230
@ CMD_SELECT
Definition nodes.h:273
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
@ RTE_FUNCTION
#define ACL_EXECUTE
Definition parsenodes.h:83
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
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
#define PointerGetDatum(X)
Definition postgres.h:354
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition setrefs.c:3599
void check_stack_depth(void)
Definition stack_depth.c:96
struct ErrorContextCallback * previous
Definition elog.h:299
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

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

◆ is_parallel_safe()

bool is_parallel_safe ( PlannerInfo root,
Node node 
)
extern

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)
extern

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}
bool contain_var_clause(Node *node)
Definition var.c:406

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 
)
extern

Definition at line 2369 of file clauses.c.

2370{
2371 if (bms_is_empty(relids) &&
2373 return true;
2374 return false;
2375}
#define bms_is_empty(a)
Definition bitmapset.h:119

References bms_is_empty, and contain_volatile_functions().

Referenced by clauselist_selectivity_ext().

◆ max_parallel_hazard()

char max_parallel_hazard ( Query parse)
extern

◆ NumRelids()

int NumRelids ( PlannerInfo root,
Node clause 
)
extern

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)
extern

Definition at line 6259 of file clauses.c.

6260{
6262
6263 (void) pull_paramids_walker((Node *) expr, &result);
6264
6265 return result;
6266}
static bool pull_paramids_walker(Node *node, Bitmapset **context)
Definition clauses.c:6269

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

Referenced by create_memoize_plan().

◆ query_outputs_are_not_nullable()

bool query_outputs_are_not_nullable ( Query query)
extern

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:1147
static void find_subquery_safe_quals(Node *jtnode, List **safe_quals)
Definition clauses.c:2205
List * find_nonnullable_vars(Node *clause)
Definition clauses.c:1743
bool expr_is_nonnullable(PlannerInfo *root, Expr *expr, NotNullSource source)
Definition clauses.c:4804
bool mbms_is_member(int listidx, int bitidx, const List *a)
@ NOTNULL_SOURCE_CATALOG
Definition optimizer.h:138
#define foreach_node(type, var, lst)
Definition pg_list.h:528
Query * parse
Definition pathnodes.h:309
FromExpr * jointree
Definition parsenodes.h:187
Node * setOperations
Definition parsenodes.h:240
List * targetList
Definition parsenodes.h:203
List * groupingSets
Definition parsenodes.h:224
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().