PostgreSQL Source Code git master
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
 

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

Function Documentation

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)

Definition at line 2162 of file clauses.c.

2163{
2164 Oid opoid;
2165 Node *temp;
2166
2167 /* Sanity checks: caller is at fault if these fail */
2168 if (!is_opclause(clause) ||
2169 list_length(clause->args) != 2)
2170 elog(ERROR, "cannot commute non-binary-operator clause");
2171
2172 opoid = get_commutator(clause->opno);
2173
2174 if (!OidIsValid(opoid))
2175 elog(ERROR, "could not find commutator for operator %u",
2176 clause->opno);
2177
2178 /*
2179 * modify the clause in-place!
2180 */
2181 clause->opno = opoid;
2182 clause->opfuncid = InvalidOid;
2183 /* opresulttype, opretset, opcollid, inputcollid need not change */
2184
2185 temp = linitial(clause->args);
2186 linitial(clause->args) = lsecond(clause->args);
2187 lsecond(clause->args) = temp;
2188}
#define OidIsValid(objectId)
Definition: c.h:777
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1676
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
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
Definition: nodes.h:135
Oid opno
Definition: primnodes.h:850
List * args
Definition: primnodes.h:868

References OpExpr::args, elog, ERROR, 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 190 of file clauses.c.

191{
192 return contain_agg_clause_walker(clause, NULL);
193}
static bool contain_agg_clause_walker(Node *node, void *context)
Definition: clauses.c:196

References contain_agg_clause_walker().

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 
)

Definition at line 1151 of file clauses.c.

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

References contain_exec_param_walker().

Referenced by test_opexpr_is_hashable().

◆ contain_leaked_vars()

bool contain_leaked_vars ( Node clause)

Definition at line 1277 of file clauses.c.

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

References contain_leaked_vars_walker().

Referenced by make_plain_restrictinfo(), and qual_is_pushdown_safe().

◆ contain_nonstrict_functions()

bool contain_nonstrict_functions ( Node clause)

Definition at line 1005 of file clauses.c.

1006{
1007 return contain_nonstrict_functions_walker(clause, NULL);
1008}
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition: clauses.c:1017

References contain_nonstrict_functions_walker().

Referenced by inline_function(), and pullup_replace_vars_callback().

◆ contain_subplans()

bool contain_subplans ( Node clause)

◆ contain_window_function()

bool contain_window_function ( Node clause)

Definition at line 227 of file clauses.c.

228{
229 return contain_windowfuncs(clause);
230}
bool contain_windowfuncs(Node *node)
Definition: rewriteManip.c:214

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr(), and mark_nullable_by_grouping().

◆ expression_returns_set_rows()

double expression_returns_set_rows ( PlannerInfo root,
Node clause 
)

Definition at line 301 of file clauses.c.

302{
303 if (clause == NULL)
304 return 1.0;
305 if (IsA(clause, FuncExpr))
306 {
307 FuncExpr *expr = (FuncExpr *) clause;
308
309 if (expr->funcretset)
310 return clamp_row_est(get_function_rows(root, expr->funcid, clause));
311 }
312 if (IsA(clause, OpExpr))
313 {
314 OpExpr *expr = (OpExpr *) clause;
315
316 if (expr->opretset)
317 {
318 set_opfuncid(expr);
319 return clamp_row_est(get_function_rows(root, expr->opfuncid, clause));
320 }
321 }
322 return 1.0;
323}
double clamp_row_est(double nrows)
Definition: costsize.c:213
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1868
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition: plancat.c:2377
tree ctl root
Definition: radixtree.h:1857
Oid funcid
Definition: primnodes.h:782

References clamp_row_est(), 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)

Definition at line 1992 of file clauses.c.

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

References NullTest::arg, BooleanTest::arg, BooleanTest::booltesttype, if(), 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 1931 of file clauses.c.

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

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

Referenced by find_forced_null_vars(), and reduce_outer_joins_pass2().

◆ find_nonnullable_rels()

Relids find_nonnullable_rels ( Node clause)

Definition at line 1471 of file clauses.c.

1472{
1473 return find_nonnullable_rels_walker(clause, true);
1474}
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition: clauses.c:1477

References find_nonnullable_rels_walker().

Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().

◆ find_nonnullable_vars()

List * find_nonnullable_vars ( Node clause)

Definition at line 1722 of file clauses.c.

1723{
1724 return find_nonnullable_vars_walker(clause, true);
1725}
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition: clauses.c:1728

References find_nonnullable_vars_walker().

Referenced by reduce_outer_joins_pass2().

◆ find_window_functions()

WindowFuncLists * find_window_functions ( Node clause,
Index  maxWinRef 
)

Definition at line 240 of file clauses.c.

241{
242 WindowFuncLists *lists = palloc(sizeof(WindowFuncLists));
243
244 lists->numWindowFuncs = 0;
245 lists->maxWinRef = maxWinRef;
246 lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
247 (void) find_window_functions_walker(clause, lists);
248 return lists;
249}
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition: clauses.c:252
void * palloc0(Size size)
Definition: mcxt.c:1395
void * palloc(Size size)
Definition: mcxt.c:1365
List ** windowFuncs
Definition: clauses.h:23
Index maxWinRef
Definition: clauses.h:22
int numWindowFuncs
Definition: clauses.h:21

References find_window_functions_walker(), WindowFuncLists::maxWinRef, WindowFuncLists::numWindowFuncs, palloc(), palloc0(), and WindowFuncLists::windowFuncs.

Referenced by grouping_planner().

◆ inline_function_in_from()

Query * inline_function_in_from ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 5249 of file clauses.c.

5250{
5251 RangeTblFunction *rtfunc;
5252 FuncExpr *fexpr;
5253 Oid func_oid;
5254 HeapTuple func_tuple;
5255 Form_pg_proc funcform;
5256 MemoryContext oldcxt;
5257 MemoryContext mycxt;
5258 Datum tmp;
5259 char *src;
5260 inline_error_callback_arg callback_arg;
5261 ErrorContextCallback sqlerrcontext;
5262 Query *querytree = NULL;
5263
5264 Assert(rte->rtekind == RTE_FUNCTION);
5265
5266 /*
5267 * Guard against infinite recursion during expansion by checking for stack
5268 * overflow. (There's no need to do more.)
5269 */
5271
5272 /* Fail if the RTE has ORDINALITY - we don't implement that here. */
5273 if (rte->funcordinality)
5274 return NULL;
5275
5276 /* Fail if RTE isn't a single, simple FuncExpr */
5277 if (list_length(rte->functions) != 1)
5278 return NULL;
5279 rtfunc = (RangeTblFunction *) linitial(rte->functions);
5280
5281 if (!IsA(rtfunc->funcexpr, FuncExpr))
5282 return NULL;
5283 fexpr = (FuncExpr *) rtfunc->funcexpr;
5284
5285 func_oid = fexpr->funcid;
5286
5287 /*
5288 * Refuse to inline if the arguments contain any volatile functions or
5289 * sub-selects. Volatile functions are rejected because inlining may
5290 * result in the arguments being evaluated multiple times, risking a
5291 * change in behavior. Sub-selects are rejected partly for implementation
5292 * reasons (pushing them down another level might change their behavior)
5293 * and partly because they're likely to be expensive and so multiple
5294 * evaluation would be bad.
5295 */
5296 if (contain_volatile_functions((Node *) fexpr->args) ||
5297 contain_subplans((Node *) fexpr->args))
5298 return NULL;
5299
5300 /* Check permission to call function (fail later, if not) */
5301 if (object_aclcheck(ProcedureRelationId, func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
5302 return NULL;
5303
5304 /* Check whether a plugin wants to hook function entry/exit */
5305 if (FmgrHookIsNeeded(func_oid))
5306 return NULL;
5307
5308 /*
5309 * OK, let's take a look at the function's pg_proc entry.
5310 */
5311 func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid));
5312 if (!HeapTupleIsValid(func_tuple))
5313 elog(ERROR, "cache lookup failed for function %u", func_oid);
5314 funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
5315
5316 /*
5317 * If the function SETs any configuration parameters, inlining would cause
5318 * us to miss making those changes.
5319 */
5320 if (!heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL))
5321 {
5322 ReleaseSysCache(func_tuple);
5323 return NULL;
5324 }
5325
5326 /*
5327 * Make a temporary memory context, so that we don't leak all the stuff
5328 * that parsing and rewriting might create. If we succeed, we'll copy
5329 * just the finished query tree back up to the caller's context.
5330 */
5332 "inline_function_in_from",
5334 oldcxt = MemoryContextSwitchTo(mycxt);
5335
5336 /* Fetch the function body */
5337 tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
5338 src = TextDatumGetCString(tmp);
5339
5340 /*
5341 * If the function has an attached support function that can handle
5342 * SupportRequestInlineInFrom, then attempt to inline with that.
5343 */
5344 if (funcform->prosupport)
5345 {
5347
5348 req.type = T_SupportRequestInlineInFrom;
5349 req.root = root;
5350 req.rtfunc = rtfunc;
5351 req.proc = func_tuple;
5352
5353 querytree = (Query *)
5354 DatumGetPointer(OidFunctionCall1(funcform->prosupport,
5355 PointerGetDatum(&req)));
5356 }
5357
5358 /*
5359 * Setup error traceback support for ereport(). This is so that we can
5360 * finger the function that bad information came from. We don't install
5361 * this while running the support function, since it'd be likely to do the
5362 * wrong thing: any parse errors reported during that are very likely not
5363 * against the raw function source text.
5364 */
5365 callback_arg.proname = NameStr(funcform->proname);
5366 callback_arg.prosrc = src;
5367
5368 sqlerrcontext.callback = sql_inline_error_callback;
5369 sqlerrcontext.arg = &callback_arg;
5370 sqlerrcontext.previous = error_context_stack;
5371 error_context_stack = &sqlerrcontext;
5372
5373 /*
5374 * If SupportRequestInlineInFrom didn't work, try our built-in inlining
5375 * mechanism.
5376 */
5377 if (!querytree)
5379 func_tuple, funcform, src);
5380
5381 if (!querytree)
5382 goto fail; /* no luck there either, fail */
5383
5384 /*
5385 * The result had better be a SELECT Query.
5386 */
5388 Assert(querytree->commandType == CMD_SELECT);
5389
5390 /*
5391 * Looks good --- substitute parameters into the query.
5392 */
5394 funcform->pronargs,
5395 fexpr->args);
5396
5397 /*
5398 * Copy the modified query out of the temporary memory context, and clean
5399 * up.
5400 */
5401 MemoryContextSwitchTo(oldcxt);
5402
5404
5405 MemoryContextDelete(mycxt);
5406 error_context_stack = sqlerrcontext.previous;
5407 ReleaseSysCache(func_tuple);
5408
5409 /*
5410 * We don't have to fix collations here because the upper query is already
5411 * parsed, ie, the collations in the RTE are what count.
5412 */
5413
5414 /*
5415 * Since there is now no trace of the function in the plan tree, we must
5416 * explicitly record the plan's dependency on the function.
5417 */
5419
5420 /*
5421 * We must also notice if the inserted query adds a dependency on the
5422 * calling role due to RLS quals.
5423 */
5424 if (querytree->hasRowSecurity)
5425 root->glob->dependsOnRole = true;
5426
5427 return querytree;
5428
5429 /* Here if func is not inlinable: release temp memory and return NULL */
5430fail:
5431 MemoryContextSwitchTo(oldcxt);
5432 MemoryContextDelete(mycxt);
5433 error_context_stack = sqlerrcontext.previous;
5434 ReleaseSysCache(func_tuple);
5435
5436 return NULL;
5437}
Datum querytree(PG_FUNCTION_ARGS)
Definition: _int_bool.c:665
@ ACLCHECK_OK
Definition: acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3834
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:754
static Query * substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
Definition: clauses.c:5613
static void sql_inline_error_callback(void *arg)
Definition: clauses.c:5133
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:5453
bool contain_subplans(Node *clause)
Definition: clauses.c:342
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:550
ErrorContextCallback * error_context_stack
Definition: elog.c:95
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:720
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:848
Assert(PointerIsAligned(start, uint64))
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)
Definition: htup_details.h:728
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
Oid GetUserId(void)
Definition: miscinit.c:469
#define copyObject(obj)
Definition: nodes.h:232
@ CMD_SELECT
Definition: nodes.h:275
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
@ RTE_FUNCTION
Definition: parsenodes.h:1046
#define ACL_EXECUTE
Definition: parsenodes.h:83
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition: setrefs.c:3575
void check_stack_depth(void)
Definition: stack_depth.c:95
struct ErrorContextCallback * previous
Definition: elog.h:297
void(* callback)(void *arg)
Definition: elog.h:298
List * args
Definition: primnodes.h:800
bool funcordinality
Definition: parsenodes.h:1210
List * functions
Definition: parsenodes.h:1208
RTEKind rtekind
Definition: parsenodes.h:1078
RangeTblFunction * rtfunc
Definition: supportnodes.h:123
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:625

References ACL_EXECUTE, ACLCHECK_OK, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ErrorContextCallback::arg, FuncExpr::args, Assert(), ErrorContextCallback::callback, check_stack_depth(), CMD_SELECT, contain_subplans(), contain_volatile_functions(), copyObject, CurrentMemoryContext, DatumGetPointer(), elog, ERROR, error_context_stack, FmgrHookIsNeeded, RangeTblFunction::funcexpr, FuncExpr::funcid, RangeTblEntry::funcordinality, RangeTblEntry::functions, GETSTRUCT(), GetUserId(), heap_attisnull(), HeapTupleIsValid, if(), inline_sql_function_in_from(), IsA, linitial, list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, object_aclcheck(), ObjectIdGetDatum(), OidFunctionCall1, PointerGetDatum(), ErrorContextCallback::previous, SupportRequestInlineInFrom::proc, inline_error_callback_arg::proname, inline_error_callback_arg::prosrc, querytree(), record_plan_function_dependency(), ReleaseSysCache(), root, SupportRequestInlineInFrom::root, RTE_FUNCTION, RangeTblEntry::rtekind, SupportRequestInlineInFrom::rtfunc, 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 
)

Definition at line 765 of file clauses.c.

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

References PlannerInfo::init_plans, lfirst, list_concat(), max_parallel_hazard_context::max_hazard, max_parallel_hazard_context::max_interesting, max_parallel_hazard_walker(), NIL, root, max_parallel_hazard_context::safe_param_ids, and SubPlan::setParam.

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

2104{
2105 /*
2106 * We could implement this check in one recursive scan. But since the
2107 * check for volatile functions is both moderately expensive and unlikely
2108 * to fail, it seems better to look for Vars first and only check for
2109 * volatile functions if we find no Vars.
2110 */
2111 if (!contain_var_clause(clause) &&
2113 return true;
2114 return false;
2115}
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 
)

Definition at line 2123 of file clauses.c.

2124{
2125 if (bms_is_empty(relids) &&
2127 return true;
2128 return false;
2129}
#define bms_is_empty(a)
Definition: bitmapset.h:118

References bms_is_empty, and contain_volatile_functions().

Referenced by clauselist_selectivity_ext().

◆ max_parallel_hazard()

char max_parallel_hazard ( Query parse)

Definition at line 746 of file clauses.c.

747{
749
750 context.max_hazard = PROPARALLEL_SAFE;
751 context.max_interesting = PROPARALLEL_UNSAFE;
752 context.safe_param_ids = NIL;
753 (void) max_parallel_hazard_walker((Node *) parse, &context);
754 return context.max_hazard;
755}
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
Definition: regcomp.c:717

References max_parallel_hazard_context::max_hazard, max_parallel_hazard_context::max_interesting, max_parallel_hazard_walker(), NIL, parse(), and max_parallel_hazard_context::safe_param_ids.

Referenced by standard_planner().

◆ NumRelids()

int NumRelids ( PlannerInfo root,
Node clause 
)

Definition at line 2145 of file clauses.c.

2146{
2147 int result;
2148 Relids varnos = pull_varnos(root, clause);
2149
2150 varnos = bms_del_members(varnos, root->outer_join_rels);
2151 result = bms_num_members(varnos);
2152 bms_free(varnos);
2153 return result;
2154}
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:1160
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:750
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:114

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

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

◆ pull_paramids()

Bitmapset * pull_paramids ( Expr expr)

Definition at line 5673 of file clauses.c.

5674{
5675 Bitmapset *result = NULL;
5676
5677 (void) pull_paramids_walker((Node *) expr, &result);
5678
5679 return result;
5680}
static bool pull_paramids_walker(Node *node, Bitmapset **context)
Definition: clauses.c:5683

References pull_paramids_walker().

Referenced by create_memoize_plan().