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_set_returning_function (PlannerInfo *root, RangeTblEntry *rte)
 
Bitmapsetpull_paramids (Expr *expr)
 

Function Documentation

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)

Definition at line 2064 of file clauses.c.

2065 {
2066  Oid opoid;
2067  Node *temp;
2068 
2069  /* Sanity checks: caller is at fault if these fail */
2070  if (!is_opclause(clause) ||
2071  list_length(clause->args) != 2)
2072  elog(ERROR, "cannot commute non-binary-operator clause");
2073 
2074  opoid = get_commutator(clause->opno);
2075 
2076  if (!OidIsValid(opoid))
2077  elog(ERROR, "could not find commutator for operator %u",
2078  clause->opno);
2079 
2080  /*
2081  * modify the clause in-place!
2082  */
2083  clause->opno = opoid;
2084  clause->opfuncid = InvalidOid;
2085  /* opresulttype, opretset, opcollid, inputcollid need not change */
2086 
2087  temp = linitial(clause->args);
2088  linitial(clause->args) = lsecond(clause->args);
2089  lsecond(clause->args) = temp;
2090 }
#define OidIsValid(objectId)
Definition: c.h:764
#define ERROR
Definition: elog.h:39
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1513
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:74
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:36
unsigned int Oid
Definition: postgres_ext.h:31
Definition: nodes.h:129
Oid opno
Definition: primnodes.h:745
List * args
Definition: primnodes.h:763

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

180 {
181  return contain_agg_clause_walker(clause, NULL);
182 }
static bool contain_agg_clause_walker(Node *node, void *context)
Definition: clauses.c:185

References contain_agg_clause_walker().

Referenced by get_eclass_for_sort_expr(), and subquery_planner().

◆ contain_exec_param()

bool contain_exec_param ( Node clause,
List param_ids 
)

Definition at line 1054 of file clauses.c.

1055 {
1056  return contain_exec_param_walker(clause, param_ids);
1057 }
static bool contain_exec_param_walker(Node *node, List *param_ids)
Definition: clauses.c:1060

References contain_exec_param_walker().

Referenced by test_opexpr_is_hashable().

◆ contain_leaked_vars()

bool contain_leaked_vars ( Node clause)

Definition at line 1180 of file clauses.c.

1181 {
1182  return contain_leaked_vars_walker(clause, NULL);
1183 }
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition: clauses.c:1192

References contain_leaked_vars_walker().

Referenced by make_restrictinfo_internal(), and qual_is_pushdown_safe().

◆ contain_nonstrict_functions()

bool contain_nonstrict_functions ( Node clause)

Definition at line 910 of file clauses.c.

911 {
912  return contain_nonstrict_functions_walker(clause, NULL);
913 }
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition: clauses.c:922

References contain_nonstrict_functions_walker().

Referenced by inline_function().

◆ contain_subplans()

bool contain_subplans ( Node clause)

Definition at line 332 of file clauses.c.

333 {
334  return contain_subplans_walker(clause, NULL);
335 }
static bool contain_subplans_walker(Node *node, void *context)
Definition: clauses.c:338

References contain_subplans_walker().

Referenced by convert_EXISTS_to_ANY(), ExecInitValuesScan(), find_window_run_conditions(), initialize_peragg(), inline_function(), inline_set_returning_function(), qual_is_pushdown_safe(), and subquery_planner().

◆ contain_window_function()

bool contain_window_function ( Node clause)

Definition at line 216 of file clauses.c.

217 {
218  return contain_windowfuncs(clause);
219 }
bool contain_windowfuncs(Node *node)
Definition: rewriteManip.c:215

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr().

◆ expression_returns_set_rows()

double expression_returns_set_rows ( PlannerInfo root,
Node clause 
)

Definition at line 291 of file clauses.c.

292 {
293  if (clause == NULL)
294  return 1.0;
295  if (IsA(clause, FuncExpr))
296  {
297  FuncExpr *expr = (FuncExpr *) clause;
298 
299  if (expr->funcretset)
300  return clamp_row_est(get_function_rows(root, expr->funcid, clause));
301  }
302  if (IsA(clause, OpExpr))
303  {
304  OpExpr *expr = (OpExpr *) clause;
305 
306  if (expr->opretset)
307  {
308  set_opfuncid(expr);
309  return clamp_row_est(get_function_rows(root, expr->opfuncid, clause));
310  }
311  }
312  return 1.0;
313 }
double clamp_row_est(double nrows)
Definition: costsize.c:203
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1779
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition: plancat.c:2104
Oid funcid
Definition: primnodes.h:677

References clamp_row_est(), FuncExpr::funcid, get_function_rows(), IsA, 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 1894 of file clauses.c.

1895 {
1896  if (node == NULL)
1897  return NULL;
1898  if (IsA(node, NullTest))
1899  {
1900  /* check for var IS NULL */
1901  NullTest *expr = (NullTest *) node;
1902 
1903  if (expr->nulltesttype == IS_NULL && !expr->argisrow)
1904  {
1905  Var *var = (Var *) expr->arg;
1906 
1907  if (var && IsA(var, Var) &&
1908  var->varlevelsup == 0)
1909  return var;
1910  }
1911  }
1912  else if (IsA(node, BooleanTest))
1913  {
1914  /* var IS UNKNOWN is equivalent to var IS NULL */
1915  BooleanTest *expr = (BooleanTest *) node;
1916 
1917  if (expr->booltesttype == IS_UNKNOWN)
1918  {
1919  Var *var = (Var *) expr->arg;
1920 
1921  if (var && IsA(var, Var) &&
1922  var->varlevelsup == 0)
1923  return var;
1924  }
1925  }
1926  return NULL;
1927 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
@ IS_UNKNOWN
Definition: primnodes.h:1710
@ IS_NULL
Definition: primnodes.h:1686
BoolTestType booltesttype
Definition: primnodes.h:1717
Expr * arg
Definition: primnodes.h:1716
NullTestType nulltesttype
Definition: primnodes.h:1693
Expr * arg
Definition: primnodes.h:1692
Definition: primnodes.h:226
Index varlevelsup
Definition: primnodes.h:258

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

1834 {
1835  List *result = NIL;
1836  Var *var;
1837  ListCell *l;
1838 
1839  if (node == NULL)
1840  return NIL;
1841  /* Check single-clause cases using subroutine */
1842  var = find_forced_null_var(node);
1843  if (var)
1844  {
1845  result = mbms_add_member(result,
1846  var->varno,
1848  }
1849  /* Otherwise, handle AND-conditions */
1850  else if (IsA(node, List))
1851  {
1852  /*
1853  * At top level, we are examining an implicit-AND list: if any of the
1854  * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
1855  */
1856  foreach(l, (List *) node)
1857  {
1858  result = mbms_add_members(result,
1860  }
1861  }
1862  else if (IsA(node, BoolExpr))
1863  {
1864  BoolExpr *expr = (BoolExpr *) node;
1865 
1866  /*
1867  * We don't bother considering the OR case, because it's fairly
1868  * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
1869  * the NOT case isn't worth expending code on.
1870  */
1871  if (expr->boolop == AND_EXPR)
1872  {
1873  /* At top level we can just recurse (to the List case) */
1874  result = find_forced_null_vars((Node *) expr->args);
1875  }
1876  }
1877  return result;
1878 }
Var * find_forced_null_var(Node *node)
Definition: clauses.c:1894
List * find_forced_null_vars(Node *node)
Definition: clauses.c:1833
List * mbms_add_member(List *a, int listidx, int bitidx)
List * mbms_add_members(List *a, const List *b)
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
@ AND_EXPR
Definition: primnodes.h:858
BoolExprType boolop
Definition: primnodes.h:866
List * args
Definition: primnodes.h:867
Definition: pg_list.h:54
AttrNumber varattno
Definition: primnodes.h:238
int varno
Definition: primnodes.h:233
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27

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

Referenced by reduce_outer_joins_pass2().

◆ find_nonnullable_rels()

Relids find_nonnullable_rels ( Node clause)

Definition at line 1373 of file clauses.c.

1374 {
1375  return find_nonnullable_rels_walker(clause, true);
1376 }
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition: clauses.c:1379

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

1625 {
1626  return find_nonnullable_vars_walker(clause, true);
1627 }
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition: clauses.c:1630

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

230 {
231  WindowFuncLists *lists = palloc(sizeof(WindowFuncLists));
232 
233  lists->numWindowFuncs = 0;
234  lists->maxWinRef = maxWinRef;
235  lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
236  (void) find_window_functions_walker(clause, lists);
237  return lists;
238 }
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition: clauses.c:241
void * palloc0(Size size)
Definition: mcxt.c:1257
void * palloc(Size size)
Definition: mcxt.c:1226
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_set_returning_function()

Query* inline_set_returning_function ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 4958 of file clauses.c.

4959 {
4960  RangeTblFunction *rtfunc;
4961  FuncExpr *fexpr;
4962  Oid func_oid;
4963  HeapTuple func_tuple;
4964  Form_pg_proc funcform;
4965  char *src;
4966  Datum tmp;
4967  bool isNull;
4968  MemoryContext oldcxt;
4969  MemoryContext mycxt;
4970  inline_error_callback_arg callback_arg;
4971  ErrorContextCallback sqlerrcontext;
4973  TypeFuncClass functypclass;
4974  TupleDesc rettupdesc;
4975  List *raw_parsetree_list;
4976  List *querytree_list;
4977  Query *querytree;
4978 
4979  Assert(rte->rtekind == RTE_FUNCTION);
4980 
4981  /*
4982  * It doesn't make a lot of sense for a SQL SRF to refer to itself in its
4983  * own FROM clause, since that must cause infinite recursion at runtime.
4984  * It will cause this code to recurse too, so check for stack overflow.
4985  * (There's no need to do more.)
4986  */
4988 
4989  /* Fail if the RTE has ORDINALITY - we don't implement that here. */
4990  if (rte->funcordinality)
4991  return NULL;
4992 
4993  /* Fail if RTE isn't a single, simple FuncExpr */
4994  if (list_length(rte->functions) != 1)
4995  return NULL;
4996  rtfunc = (RangeTblFunction *) linitial(rte->functions);
4997 
4998  if (!IsA(rtfunc->funcexpr, FuncExpr))
4999  return NULL;
5000  fexpr = (FuncExpr *) rtfunc->funcexpr;
5001 
5002  func_oid = fexpr->funcid;
5003 
5004  /*
5005  * The function must be declared to return a set, else inlining would
5006  * change the results if the contained SELECT didn't return exactly one
5007  * row.
5008  */
5009  if (!fexpr->funcretset)
5010  return NULL;
5011 
5012  /*
5013  * Refuse to inline if the arguments contain any volatile functions or
5014  * sub-selects. Volatile functions are rejected because inlining may
5015  * result in the arguments being evaluated multiple times, risking a
5016  * change in behavior. Sub-selects are rejected partly for implementation
5017  * reasons (pushing them down another level might change their behavior)
5018  * and partly because they're likely to be expensive and so multiple
5019  * evaluation would be bad.
5020  */
5021  if (contain_volatile_functions((Node *) fexpr->args) ||
5022  contain_subplans((Node *) fexpr->args))
5023  return NULL;
5024 
5025  /* Check permission to call function (fail later, if not) */
5026  if (object_aclcheck(ProcedureRelationId, func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
5027  return NULL;
5028 
5029  /* Check whether a plugin wants to hook function entry/exit */
5030  if (FmgrHookIsNeeded(func_oid))
5031  return NULL;
5032 
5033  /*
5034  * OK, let's take a look at the function's pg_proc entry.
5035  */
5036  func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid));
5037  if (!HeapTupleIsValid(func_tuple))
5038  elog(ERROR, "cache lookup failed for function %u", func_oid);
5039  funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
5040 
5041  /*
5042  * Forget it if the function is not SQL-language or has other showstopper
5043  * properties. In particular it mustn't be declared STRICT, since we
5044  * couldn't enforce that. It also mustn't be VOLATILE, because that is
5045  * supposed to cause it to be executed with its own snapshot, rather than
5046  * sharing the snapshot of the calling query. We also disallow returning
5047  * SETOF VOID, because inlining would result in exposing the actual result
5048  * of the function's last SELECT, which should not happen in that case.
5049  * (Rechecking prokind, proretset, and pronargs is just paranoia.)
5050  */
5051  if (funcform->prolang != SQLlanguageId ||
5052  funcform->prokind != PROKIND_FUNCTION ||
5053  funcform->proisstrict ||
5054  funcform->provolatile == PROVOLATILE_VOLATILE ||
5055  funcform->prorettype == VOIDOID ||
5056  funcform->prosecdef ||
5057  !funcform->proretset ||
5058  list_length(fexpr->args) != funcform->pronargs ||
5059  !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL))
5060  {
5061  ReleaseSysCache(func_tuple);
5062  return NULL;
5063  }
5064 
5065  /*
5066  * Make a temporary memory context, so that we don't leak all the stuff
5067  * that parsing might create.
5068  */
5070  "inline_set_returning_function",
5072  oldcxt = MemoryContextSwitchTo(mycxt);
5073 
5074  /* Fetch the function body */
5075  tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);
5076  src = TextDatumGetCString(tmp);
5077 
5078  /*
5079  * Setup error traceback support for ereport(). This is so that we can
5080  * finger the function that bad information came from.
5081  */
5082  callback_arg.proname = NameStr(funcform->proname);
5083  callback_arg.prosrc = src;
5084 
5085  sqlerrcontext.callback = sql_inline_error_callback;
5086  sqlerrcontext.arg = (void *) &callback_arg;
5087  sqlerrcontext.previous = error_context_stack;
5088  error_context_stack = &sqlerrcontext;
5089 
5090  /* If we have prosqlbody, pay attention to that not prosrc */
5091  tmp = SysCacheGetAttr(PROCOID,
5092  func_tuple,
5093  Anum_pg_proc_prosqlbody,
5094  &isNull);
5095  if (!isNull)
5096  {
5097  Node *n;
5098 
5100  if (IsA(n, List))
5101  querytree_list = linitial_node(List, castNode(List, n));
5102  else
5103  querytree_list = list_make1(n);
5104  if (list_length(querytree_list) != 1)
5105  goto fail;
5106  querytree = linitial(querytree_list);
5107 
5108  /* Acquire necessary locks, then apply rewriter. */
5109  AcquireRewriteLocks(querytree, true, false);
5110  querytree_list = pg_rewrite_query(querytree);
5111  if (list_length(querytree_list) != 1)
5112  goto fail;
5113  querytree = linitial(querytree_list);
5114  }
5115  else
5116  {
5117  /*
5118  * Set up to handle parameters while parsing the function body. We
5119  * can use the FuncExpr just created as the input for
5120  * prepare_sql_fn_parse_info.
5121  */
5122  pinfo = prepare_sql_fn_parse_info(func_tuple,
5123  (Node *) fexpr,
5124  fexpr->inputcollid);
5125 
5126  /*
5127  * Parse, analyze, and rewrite (unlike inline_function(), we can't
5128  * skip rewriting here). We can fail as soon as we find more than one
5129  * query, though.
5130  */
5131  raw_parsetree_list = pg_parse_query(src);
5132  if (list_length(raw_parsetree_list) != 1)
5133  goto fail;
5134 
5135  querytree_list = pg_analyze_and_rewrite_withcb(linitial(raw_parsetree_list),
5136  src,
5138  pinfo, NULL);
5139  if (list_length(querytree_list) != 1)
5140  goto fail;
5141  querytree = linitial(querytree_list);
5142  }
5143 
5144  /*
5145  * Also resolve the actual function result tupdesc, if composite. If the
5146  * function is just declared to return RECORD, dig the info out of the AS
5147  * clause.
5148  */
5149  functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc);
5150  if (functypclass == TYPEFUNC_RECORD)
5151  rettupdesc = BuildDescFromLists(rtfunc->funccolnames,
5152  rtfunc->funccoltypes,
5153  rtfunc->funccoltypmods,
5154  rtfunc->funccolcollations);
5155 
5156  /*
5157  * The single command must be a plain SELECT.
5158  */
5159  if (!IsA(querytree, Query) ||
5160  querytree->commandType != CMD_SELECT)
5161  goto fail;
5162 
5163  /*
5164  * Make sure the function (still) returns what it's declared to. This
5165  * will raise an error if wrong, but that's okay since the function would
5166  * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5167  * coercions if needed to make the tlist expression(s) match the declared
5168  * type of the function. We also ask it to insert dummy NULL columns for
5169  * any dropped columns in rettupdesc, so that the elements of the modified
5170  * tlist match up to the attribute numbers.
5171  *
5172  * If the function returns a composite type, don't inline unless the check
5173  * shows it's returning a whole tuple result; otherwise what it's
5174  * returning is a single composite column which is not what we need.
5175  */
5176  if (!check_sql_fn_retval(list_make1(querytree_list),
5177  fexpr->funcresulttype, rettupdesc,
5178  true, NULL) &&
5179  (functypclass == TYPEFUNC_COMPOSITE ||
5180  functypclass == TYPEFUNC_COMPOSITE_DOMAIN ||
5181  functypclass == TYPEFUNC_RECORD))
5182  goto fail; /* reject not-whole-tuple-result cases */
5183 
5184  /*
5185  * check_sql_fn_retval might've inserted a projection step, but that's
5186  * fine; just make sure we use the upper Query.
5187  */
5188  querytree = linitial_node(Query, querytree_list);
5189 
5190  /*
5191  * Looks good --- substitute parameters into the query.
5192  */
5194  funcform->pronargs,
5195  fexpr->args);
5196 
5197  /*
5198  * Copy the modified query out of the temporary memory context, and clean
5199  * up.
5200  */
5201  MemoryContextSwitchTo(oldcxt);
5202 
5204 
5205  MemoryContextDelete(mycxt);
5206  error_context_stack = sqlerrcontext.previous;
5207  ReleaseSysCache(func_tuple);
5208 
5209  /*
5210  * We don't have to fix collations here because the upper query is already
5211  * parsed, ie, the collations in the RTE are what count.
5212  */
5213 
5214  /*
5215  * Since there is now no trace of the function in the plan tree, we must
5216  * explicitly record the plan's dependency on the function.
5217  */
5218  record_plan_function_dependency(root, func_oid);
5219 
5220  /*
5221  * We must also notice if the inserted query adds a dependency on the
5222  * calling role due to RLS quals.
5223  */
5224  if (querytree->hasRowSecurity)
5225  root->glob->dependsOnRole = true;
5226 
5227  return querytree;
5228 
5229  /* Here if func is not inlinable: release temp memory and return NULL */
5230 fail:
5231  MemoryContextSwitchTo(oldcxt);
5232  MemoryContextDelete(mycxt);
5233  error_context_stack = sqlerrcontext.previous;
5234  ReleaseSysCache(func_tuple);
5235 
5236  return NULL;
5237 }
Datum querytree(PG_FUNCTION_ARGS)
Definition: _int_bool.c:666
@ ACLCHECK_OK
Definition: acl.h:182
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3760
#define TextDatumGetCString(d)
Definition: builtins.h:95
#define NameStr(name)
Definition: c.h:735
static Query * substitute_actual_srf_parameters(Query *expr, int nargs, List *args)
Definition: clauses.c:5246
static void sql_inline_error_callback(void *arg)
Definition: clauses.c:4842
bool contain_subplans(Node *clause)
Definition: clauses.c:332
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:483
ErrorContextCallback * error_context_stack
Definition: elog.c:95
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:797
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:292
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, bool insertDroppedCols, List **resultTargetList)
Definition: functions.c:1607
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
Definition: functions.c:265
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
Definition: functions.c:176
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:447
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
Assert(fmt[strlen(fmt) - 1] !='\n')
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
Oid GetUserId(void)
Definition: miscinit.c:509
#define copyObject(obj)
Definition: nodes.h:244
@ CMD_SELECT
Definition: nodes.h:276
#define castNode(_type_, nodeptr)
Definition: nodes.h:197
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
Definition: params.h:108
@ RTE_FUNCTION
Definition: parsenodes.h:1016
#define ACL_EXECUTE
Definition: parsenodes.h:90
#define linitial_node(type, l)
Definition: pg_list.h:181
#define list_make1(x1)
Definition: pg_list.h:212
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
List * pg_parse_query(const char *query_string)
Definition: postgres.c:609
List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition: postgres.c:762
List * pg_rewrite_query(Query *query)
Definition: postgres.c:802
void check_stack_depth(void)
Definition: postgres.c:3523
uintptr_t Datum
Definition: postgres.h:64
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
void * stringToNode(const char *str)
Definition: read.c:90
void AcquireRewriteLocks(Query *parsetree, bool forExecute, bool forUpdatePushedDown)
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition: setrefs.c:3438
struct ErrorContextCallback * previous
Definition: elog.h:295
void(* callback)(void *arg)
Definition: elog.h:296
List * args
Definition: primnodes.h:695
bool dependsOnRole
Definition: pathnodes.h:150
PlannerGlobal * glob
Definition: pathnodes.h:202
bool funcordinality
Definition: parsenodes.h:1148
List * functions
Definition: parsenodes.h:1147
RTEKind rtekind
Definition: parsenodes.h:1032
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1081
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:1112
@ PROCOID
Definition: syscache.h:79
TupleDesc BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
Definition: tupdesc.c:894

References ACL_EXECUTE, ACLCHECK_OK, AcquireRewriteLocks(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ErrorContextCallback::arg, FuncExpr::args, Assert(), BuildDescFromLists(), ErrorContextCallback::callback, castNode, check_sql_fn_retval(), check_stack_depth(), CMD_SELECT, contain_subplans(), contain_volatile_functions(), copyObject, CurrentMemoryContext, PlannerGlobal::dependsOnRole, elog(), ERROR, error_context_stack, FmgrHookIsNeeded, RangeTblFunction::funcexpr, FuncExpr::funcid, RangeTblEntry::funcordinality, RangeTblEntry::functions, get_expr_result_type(), GETSTRUCT, GetUserId(), PlannerInfo::glob, heap_attisnull(), HeapTupleIsValid, if(), IsA, linitial, linitial_node, list_length(), list_make1, MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, object_aclcheck(), ObjectIdGetDatum(), pg_analyze_and_rewrite_withcb(), pg_parse_query(), pg_rewrite_query(), prepare_sql_fn_parse_info(), ErrorContextCallback::previous, PROCOID, inline_error_callback_arg::proname, inline_error_callback_arg::prosrc, querytree(), record_plan_function_dependency(), ReleaseSysCache(), RTE_FUNCTION, RangeTblEntry::rtekind, SearchSysCache1(), sql_fn_parser_setup(), sql_inline_error_callback(), stringToNode(), substitute_actual_srf_parameters(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, and TYPEFUNC_RECORD.

Referenced by preprocess_function_rtes().

◆ is_parallel_safe()

bool is_parallel_safe ( PlannerInfo root,
Node node 
)

Definition at line 670 of file clauses.c.

671 {
673  PlannerInfo *proot;
674  ListCell *l;
675 
676  /*
677  * Even if the original querytree contained nothing unsafe, we need to
678  * search the expression if we have generated any PARAM_EXEC Params while
679  * planning, because those are parallel-restricted and there might be one
680  * in this expression. But otherwise we don't need to look.
681  */
682  if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
683  root->glob->paramExecTypes == NIL)
684  return true;
685  /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
686  context.max_hazard = PROPARALLEL_SAFE;
687  context.max_interesting = PROPARALLEL_RESTRICTED;
688  context.safe_param_ids = NIL;
689 
690  /*
691  * The params that refer to the same or parent query level are considered
692  * parallel-safe. The idea is that we compute such params at Gather or
693  * Gather Merge node and pass their value to workers.
694  */
695  for (proot = root; proot != NULL; proot = proot->parent_root)
696  {
697  foreach(l, proot->init_plans)
698  {
699  SubPlan *initsubplan = (SubPlan *) lfirst(l);
700 
701  context.safe_param_ids = list_concat(context.safe_param_ids,
702  initsubplan->setParam);
703  }
704  }
705 
706  return !max_parallel_hazard_walker(node, &context);
707 }
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:746
List * list_concat(List *list1, const List *list2)
Definition: list.c:560
char maxParallelHazard
Definition: pathnodes.h:159
List * paramExecTypes
Definition: pathnodes.h:135
List * init_plans
Definition: pathnodes.h:296
List * setParam
Definition: primnodes.h:1015

References PlannerInfo::glob, PlannerInfo::init_plans, lfirst, list_concat(), max_parallel_hazard_context::max_hazard, max_parallel_hazard_context::max_interesting, max_parallel_hazard_walker(), PlannerGlobal::maxParallelHazard, NIL, PlannerGlobal::paramExecTypes, max_parallel_hazard_context::safe_param_ids, and SubPlan::setParam.

Referenced by apply_projection_to_path(), build_join_rel(), create_minmaxagg_path(), 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 2005 of file clauses.c.

2006 {
2007  /*
2008  * We could implement this check in one recursive scan. But since the
2009  * check for volatile functions is both moderately expensive and unlikely
2010  * to fail, it seems better to look for Vars first and only check for
2011  * volatile functions if we find no Vars.
2012  */
2013  if (!contain_var_clause(clause) &&
2014  !contain_volatile_functions(clause))
2015  return true;
2016  return false;
2017 }
bool contain_var_clause(Node *node)
Definition: var.c:403

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

2026 {
2027  if (bms_is_empty(relids) &&
2028  !contain_volatile_functions(clause))
2029  return true;
2030  return false;
2031 }
#define bms_is_empty(a)
Definition: bitmapset.h:105

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

652 {
654 
655  context.max_hazard = PROPARALLEL_SAFE;
656  context.max_interesting = PROPARALLEL_UNSAFE;
657  context.safe_param_ids = NIL;
658  (void) max_parallel_hazard_walker((Node *) parse, &context);
659  return context.max_hazard;
660 }
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
Definition: regcomp.c:715

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

2048 {
2049  int result;
2050  Relids varnos = pull_varnos(root, clause);
2051 
2052  varnos = bms_del_members(varnos, root->outer_join_rels);
2053  result = bms_num_members(varnos);
2054  bms_free(varnos);
2055  return result;
2056 }
void bms_free(Bitmapset *a)
Definition: bitmapset.c:194
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:685
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:993
Relids outer_join_rels
Definition: pathnodes.h:258
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:108

References bms_del_members(), bms_free(), bms_num_members(), PlannerInfo::outer_join_rels, and pull_varnos().

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

◆ pull_paramids()

Bitmapset* pull_paramids ( Expr expr)

Definition at line 5306 of file clauses.c.

5307 {
5308  Bitmapset *result = NULL;
5309 
5310  (void) pull_paramids_walker((Node *) expr, &result);
5311 
5312  return result;
5313 }
static bool pull_paramids_walker(Node *node, Bitmapset **context)
Definition: clauses.c:5316

References pull_paramids_walker().

Referenced by create_memoize_plan().