PostgreSQL Source Code  git master
clauses.h File Reference
#include "access/htup.h"
#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)
 
void get_agg_clause_costs (PlannerInfo *root, Node *clause, AggSplit aggsplit, AggClauseCosts *costs)
 
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_leaked_vars (Node *clause)
 
Relids find_nonnullable_rels (Node *clause)
 
Listfind_nonnullable_vars (Node *clause)
 
Listfind_forced_null_vars (Node *clause)
 
Varfind_forced_null_var (Node *clause)
 
bool is_pseudo_constant_clause (Node *clause)
 
bool is_pseudo_constant_clause_relids (Node *clause, Relids relids)
 
int NumRelids (Node *clause)
 
void CommuteOpExpr (OpExpr *clause)
 
Queryinline_set_returning_function (PlannerInfo *root, RangeTblEntry *rte)
 

Function Documentation

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)

Definition at line 2146 of file clauses.c.

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

Referenced by get_switched_clauses().

2147 {
2148  Oid opoid;
2149  Node *temp;
2150 
2151  /* Sanity checks: caller is at fault if these fail */
2152  if (!is_opclause(clause) ||
2153  list_length(clause->args) != 2)
2154  elog(ERROR, "cannot commute non-binary-operator clause");
2155 
2156  opoid = get_commutator(clause->opno);
2157 
2158  if (!OidIsValid(opoid))
2159  elog(ERROR, "could not find commutator for operator %u",
2160  clause->opno);
2161 
2162  /*
2163  * modify the clause in-place!
2164  */
2165  clause->opno = opoid;
2166  clause->opfuncid = InvalidOid;
2167  /* opresulttype, opretset, opcollid, inputcollid need not change */
2168 
2169  temp = linitial(clause->args);
2170  linitial(clause->args) = lsecond(clause->args);
2171  lsecond(clause->args) = temp;
2172 }
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1311
Definition: nodes.h:525
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define lsecond(l)
Definition: pg_list.h:200
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
Oid opfuncid
Definition: primnodes.h:503
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:169
#define elog(elevel,...)
Definition: elog.h:226
Oid opno
Definition: primnodes.h:502
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:63
List * args
Definition: primnodes.h:508

◆ contain_agg_clause()

bool contain_agg_clause ( Node clause)

Definition at line 179 of file clauses.c.

References contain_agg_clause_walker().

Referenced by get_eclass_for_sort_expr(), and subquery_planner().

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

◆ contain_leaked_vars()

bool contain_leaked_vars ( Node clause)

Definition at line 1327 of file clauses.c.

References contain_leaked_vars_walker().

Referenced by make_restrictinfo_internal(), and qual_is_pushdown_safe().

1328 {
1329  return contain_leaked_vars_walker(clause, NULL);
1330 }
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition: clauses.c:1339

◆ contain_nonstrict_functions()

bool contain_nonstrict_functions ( Node clause)

Definition at line 1094 of file clauses.c.

References contain_nonstrict_functions_walker().

Referenced by inline_function(), process_equivalence(), and pullup_replace_vars_callback().

1095 {
1096  return contain_nonstrict_functions_walker(clause, NULL);
1097 }
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition: clauses.c:1106

◆ contain_subplans()

bool contain_subplans ( Node clause)

Definition at line 610 of file clauses.c.

References contain_subplans_walker().

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

611 {
612  return contain_subplans_walker(clause, NULL);
613 }
static bool contain_subplans_walker(Node *node, void *context)
Definition: clauses.c:616

◆ contain_window_function()

bool contain_window_function ( Node clause)

Definition at line 494 of file clauses.c.

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr(), and qual_is_pushdown_safe().

495 {
496  return contain_windowfuncs(clause);
497 }
bool contain_windowfuncs(Node *node)
Definition: rewriteManip.c:197

◆ expression_returns_set_rows()

double expression_returns_set_rows ( PlannerInfo root,
Node clause 
)

Definition at line 569 of file clauses.c.

References clamp_row_est(), FuncExpr::funcid, FuncExpr::funcretset, get_function_rows(), IsA, OpExpr::opfuncid, OpExpr::opretset, and set_opfuncid().

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

570 {
571  if (clause == NULL)
572  return 1.0;
573  if (IsA(clause, FuncExpr))
574  {
575  FuncExpr *expr = (FuncExpr *) clause;
576 
577  if (expr->funcretset)
578  return clamp_row_est(get_function_rows(root, expr->funcid, clause));
579  }
580  if (IsA(clause, OpExpr))
581  {
582  OpExpr *expr = (OpExpr *) clause;
583 
584  if (expr->opretset)
585  {
586  set_opfuncid(expr);
587  return clamp_row_est(get_function_rows(root, expr->opfuncid, clause));
588  }
589  }
590  return 1.0;
591 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
bool funcretset
Definition: primnodes.h:457
Oid funcid
Definition: primnodes.h:455
Oid opfuncid
Definition: primnodes.h:503
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1619
double clamp_row_est(double nrows)
Definition: costsize.c:187
bool opretset
Definition: primnodes.h:505
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition: plancat.c:1967

◆ find_forced_null_var()

Var* find_forced_null_var ( Node clause)

Definition at line 1978 of file clauses.c.

References NullTest::arg, BooleanTest::arg, NullTest::argisrow, BooleanTest::booltesttype, IS_NULL, IS_UNKNOWN, IsA, NullTest::nulltesttype, and Var::varlevelsup.

Referenced by check_redundant_nullability_qual(), and find_forced_null_vars().

1979 {
1980  if (node == NULL)
1981  return NULL;
1982  if (IsA(node, NullTest))
1983  {
1984  /* check for var IS NULL */
1985  NullTest *expr = (NullTest *) node;
1986 
1987  if (expr->nulltesttype == IS_NULL && !expr->argisrow)
1988  {
1989  Var *var = (Var *) expr->arg;
1990 
1991  if (var && IsA(var, Var) &&
1992  var->varlevelsup == 0)
1993  return var;
1994  }
1995  }
1996  else if (IsA(node, BooleanTest))
1997  {
1998  /* var IS UNKNOWN is equivalent to var IS NULL */
1999  BooleanTest *expr = (BooleanTest *) node;
2000 
2001  if (expr->booltesttype == IS_UNKNOWN)
2002  {
2003  Var *var = (Var *) expr->arg;
2004 
2005  if (var && IsA(var, Var) &&
2006  var->varlevelsup == 0)
2007  return var;
2008  }
2009  }
2010  return NULL;
2011 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Index varlevelsup
Definition: primnodes.h:177
Definition: primnodes.h:167
Expr * arg
Definition: primnodes.h:1205
Expr * arg
Definition: primnodes.h:1228
BoolTestType booltesttype
Definition: primnodes.h:1229
NullTestType nulltesttype
Definition: primnodes.h:1206
bool argisrow
Definition: primnodes.h:1207

◆ find_forced_null_vars()

List* find_forced_null_vars ( Node clause)

Definition at line 1919 of file clauses.c.

References AND_EXPR, BoolExpr::args, BoolExpr::boolop, find_forced_null_var(), find_forced_null_vars(), IsA, lfirst, list_concat(), list_make1, and NIL.

Referenced by find_forced_null_vars(), and reduce_outer_joins_pass2().

1920 {
1921  List *result = NIL;
1922  Var *var;
1923  ListCell *l;
1924 
1925  if (node == NULL)
1926  return NIL;
1927  /* Check single-clause cases using subroutine */
1928  var = find_forced_null_var(node);
1929  if (var)
1930  {
1931  result = list_make1(var);
1932  }
1933  /* Otherwise, handle AND-conditions */
1934  else if (IsA(node, List))
1935  {
1936  /*
1937  * At top level, we are examining an implicit-AND list: if any of the
1938  * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
1939  */
1940  foreach(l, (List *) node)
1941  {
1942  result = list_concat(result,
1944  }
1945  }
1946  else if (IsA(node, BoolExpr))
1947  {
1948  BoolExpr *expr = (BoolExpr *) node;
1949 
1950  /*
1951  * We don't bother considering the OR case, because it's fairly
1952  * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
1953  * the NOT case isn't worth expending code on.
1954  */
1955  if (expr->boolop == AND_EXPR)
1956  {
1957  /* At top level we can just recurse (to the List case) */
1958  result = find_forced_null_vars((Node *) expr->args);
1959  }
1960  }
1961  return result;
1962 }
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Definition: nodes.h:525
List * list_concat(List *list1, const List *list2)
Definition: list.c:516
Definition: primnodes.h:167
List * find_forced_null_vars(Node *node)
Definition: clauses.c:1919
#define list_make1(x1)
Definition: pg_list.h:227
BoolExprType boolop
Definition: primnodes.h:568
#define lfirst(lc)
Definition: pg_list.h:190
List * args
Definition: primnodes.h:569
Definition: pg_list.h:50
Var * find_forced_null_var(Node *node)
Definition: clauses.c:1978

◆ find_nonnullable_rels()

Relids find_nonnullable_rels ( Node clause)

Definition at line 1501 of file clauses.c.

References find_nonnullable_rels_walker().

Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().

1502 {
1503  return find_nonnullable_rels_walker(clause, true);
1504 }
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition: clauses.c:1507

◆ find_nonnullable_vars()

List* find_nonnullable_vars ( Node clause)

Definition at line 1726 of file clauses.c.

References find_nonnullable_vars_walker().

Referenced by reduce_outer_joins_pass2().

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

◆ find_window_functions()

WindowFuncLists* find_window_functions ( Node clause,
Index  maxWinRef 
)

Definition at line 507 of file clauses.c.

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

Referenced by grouping_planner().

508 {
509  WindowFuncLists *lists = palloc(sizeof(WindowFuncLists));
510 
511  lists->numWindowFuncs = 0;
512  lists->maxWinRef = maxWinRef;
513  lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
514  (void) find_window_functions_walker(clause, lists);
515  return lists;
516 }
Index maxWinRef
Definition: clauses.h:23
int numWindowFuncs
Definition: clauses.h:22
void * palloc0(Size size)
Definition: mcxt.c:980
void * palloc(Size size)
Definition: mcxt.c:949
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition: clauses.c:519
Definition: pg_list.h:50
List ** windowFuncs
Definition: clauses.h:24

◆ get_agg_clause_costs()

void get_agg_clause_costs ( PlannerInfo root,
Node clause,
AggSplit  aggsplit,
AggClauseCosts costs 
)

Definition at line 229 of file clauses.c.

References get_agg_clause_costs_context::aggsplit, get_agg_clause_costs_context::costs, get_agg_clause_costs_walker(), and get_agg_clause_costs_context::root.

Referenced by create_partial_grouping_paths(), estimate_path_cost_size(), and grouping_planner().

231 {
233 
234  context.root = root;
235  context.aggsplit = aggsplit;
236  context.costs = costs;
237  (void) get_agg_clause_costs_walker(clause, &context);
238 }
AggClauseCosts * costs
Definition: clauses.c:61
static bool get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context)
Definition: clauses.c:241

◆ inline_set_returning_function()

Query* inline_set_returning_function ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 4870 of file clauses.c.

References ACL_EXECUTE, ACLCHECK_OK, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ErrorContextCallback::arg, FuncExpr::args, Assert, ErrorContextCallback::callback, check_sql_fn_retval(), check_stack_depth(), CMD_SELECT, Query::commandType, contain_subplans(), contain_volatile_functions(), copyObject, CurrentMemoryContext, elog, ERROR, error_context_stack, FmgrHookIsNeeded, RangeTblFunction::funccoltypes, RangeTblFunction::funcexpr, FuncExpr::funcid, RangeTblEntry::funcordinality, FuncExpr::funcretset, RangeTblEntry::functions, get_func_result_type(), get_typtype(), GETSTRUCT, GetUserId(), heap_attisnull(), HeapTupleIsValid, IsA, linitial, list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, ObjectIdGetDatum, pg_analyze_and_rewrite_params(), pg_parse_query(), pg_proc_aclcheck(), 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(), substitute_actual_srf_parameters(), SysCacheGetAttr(), Query::targetList, TextDatumGetCString, tlist_matches_coltypelist(), and TYPEFUNC_RECORD.

Referenced by preprocess_function_rtes().

4871 {
4872  RangeTblFunction *rtfunc;
4873  FuncExpr *fexpr;
4874  Oid func_oid;
4875  HeapTuple func_tuple;
4876  Form_pg_proc funcform;
4877  char *src;
4878  Datum tmp;
4879  bool isNull;
4880  bool modifyTargetList;
4881  MemoryContext oldcxt;
4882  MemoryContext mycxt;
4883  inline_error_callback_arg callback_arg;
4884  ErrorContextCallback sqlerrcontext;
4886  List *raw_parsetree_list;
4887  List *querytree_list;
4888  Query *querytree;
4889 
4890  Assert(rte->rtekind == RTE_FUNCTION);
4891 
4892  /*
4893  * It doesn't make a lot of sense for a SQL SRF to refer to itself in its
4894  * own FROM clause, since that must cause infinite recursion at runtime.
4895  * It will cause this code to recurse too, so check for stack overflow.
4896  * (There's no need to do more.)
4897  */
4899 
4900  /* Fail if the RTE has ORDINALITY - we don't implement that here. */
4901  if (rte->funcordinality)
4902  return NULL;
4903 
4904  /* Fail if RTE isn't a single, simple FuncExpr */
4905  if (list_length(rte->functions) != 1)
4906  return NULL;
4907  rtfunc = (RangeTblFunction *) linitial(rte->functions);
4908 
4909  if (!IsA(rtfunc->funcexpr, FuncExpr))
4910  return NULL;
4911  fexpr = (FuncExpr *) rtfunc->funcexpr;
4912 
4913  func_oid = fexpr->funcid;
4914 
4915  /*
4916  * The function must be declared to return a set, else inlining would
4917  * change the results if the contained SELECT didn't return exactly one
4918  * row.
4919  */
4920  if (!fexpr->funcretset)
4921  return NULL;
4922 
4923  /*
4924  * Refuse to inline if the arguments contain any volatile functions or
4925  * sub-selects. Volatile functions are rejected because inlining may
4926  * result in the arguments being evaluated multiple times, risking a
4927  * change in behavior. Sub-selects are rejected partly for implementation
4928  * reasons (pushing them down another level might change their behavior)
4929  * and partly because they're likely to be expensive and so multiple
4930  * evaluation would be bad.
4931  */
4932  if (contain_volatile_functions((Node *) fexpr->args) ||
4933  contain_subplans((Node *) fexpr->args))
4934  return NULL;
4935 
4936  /* Check permission to call function (fail later, if not) */
4937  if (pg_proc_aclcheck(func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
4938  return NULL;
4939 
4940  /* Check whether a plugin wants to hook function entry/exit */
4941  if (FmgrHookIsNeeded(func_oid))
4942  return NULL;
4943 
4944  /*
4945  * OK, let's take a look at the function's pg_proc entry.
4946  */
4947  func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid));
4948  if (!HeapTupleIsValid(func_tuple))
4949  elog(ERROR, "cache lookup failed for function %u", func_oid);
4950  funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
4951 
4952  /*
4953  * Forget it if the function is not SQL-language or has other showstopper
4954  * properties. In particular it mustn't be declared STRICT, since we
4955  * couldn't enforce that. It also mustn't be VOLATILE, because that is
4956  * supposed to cause it to be executed with its own snapshot, rather than
4957  * sharing the snapshot of the calling query. We also disallow returning
4958  * SETOF VOID, because inlining would result in exposing the actual result
4959  * of the function's last SELECT, which should not happen in that case.
4960  * (Rechecking prokind, proretset, and pronargs is just paranoia.)
4961  */
4962  if (funcform->prolang != SQLlanguageId ||
4963  funcform->prokind != PROKIND_FUNCTION ||
4964  funcform->proisstrict ||
4965  funcform->provolatile == PROVOLATILE_VOLATILE ||
4966  funcform->prorettype == VOIDOID ||
4967  funcform->prosecdef ||
4968  !funcform->proretset ||
4969  list_length(fexpr->args) != funcform->pronargs ||
4970  !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL))
4971  {
4972  ReleaseSysCache(func_tuple);
4973  return NULL;
4974  }
4975 
4976  /*
4977  * Make a temporary memory context, so that we don't leak all the stuff
4978  * that parsing might create.
4979  */
4981  "inline_set_returning_function",
4983  oldcxt = MemoryContextSwitchTo(mycxt);
4984 
4985  /* Fetch the function body */
4986  tmp = SysCacheGetAttr(PROCOID,
4987  func_tuple,
4988  Anum_pg_proc_prosrc,
4989  &isNull);
4990  if (isNull)
4991  elog(ERROR, "null prosrc for function %u", func_oid);
4992  src = TextDatumGetCString(tmp);
4993 
4994  /*
4995  * Setup error traceback support for ereport(). This is so that we can
4996  * finger the function that bad information came from.
4997  */
4998  callback_arg.proname = NameStr(funcform->proname);
4999  callback_arg.prosrc = src;
5000 
5001  sqlerrcontext.callback = sql_inline_error_callback;
5002  sqlerrcontext.arg = (void *) &callback_arg;
5003  sqlerrcontext.previous = error_context_stack;
5004  error_context_stack = &sqlerrcontext;
5005 
5006  /*
5007  * Set up to handle parameters while parsing the function body. We can
5008  * use the FuncExpr just created as the input for
5009  * prepare_sql_fn_parse_info.
5010  */
5011  pinfo = prepare_sql_fn_parse_info(func_tuple,
5012  (Node *) fexpr,
5013  fexpr->inputcollid);
5014 
5015  /*
5016  * Parse, analyze, and rewrite (unlike inline_function(), we can't skip
5017  * rewriting here). We can fail as soon as we find more than one query,
5018  * though.
5019  */
5020  raw_parsetree_list = pg_parse_query(src);
5021  if (list_length(raw_parsetree_list) != 1)
5022  goto fail;
5023 
5024  querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list),
5025  src,
5027  pinfo, NULL);
5028  if (list_length(querytree_list) != 1)
5029  goto fail;
5030  querytree = linitial(querytree_list);
5031 
5032  /*
5033  * The single command must be a plain SELECT.
5034  */
5035  if (!IsA(querytree, Query) ||
5036  querytree->commandType != CMD_SELECT)
5037  goto fail;
5038 
5039  /*
5040  * Make sure the function (still) returns what it's declared to. This
5041  * will raise an error if wrong, but that's okay since the function would
5042  * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5043  * RelabelType(s) and/or NULL columns if needed to make the tlist
5044  * expression(s) match the declared type of the function.
5045  *
5046  * If the function returns a composite type, don't inline unless the check
5047  * shows it's returning a whole tuple result; otherwise what it's
5048  * returning is a single composite column which is not what we need. (Like
5049  * check_sql_fn_retval, we deliberately exclude domains over composite
5050  * here.)
5051  */
5052  if (!check_sql_fn_retval(func_oid, fexpr->funcresulttype,
5053  querytree_list,
5054  &modifyTargetList, NULL) &&
5055  (get_typtype(fexpr->funcresulttype) == TYPTYPE_COMPOSITE ||
5056  fexpr->funcresulttype == RECORDOID))
5057  goto fail; /* reject not-whole-tuple-result cases */
5058 
5059  /*
5060  * If we had to modify the tlist to make it match, and the statement is
5061  * one in which changing the tlist contents could change semantics, we
5062  * have to punt and not inline.
5063  */
5064  if (modifyTargetList)
5065  goto fail;
5066 
5067  /*
5068  * If it returns RECORD, we have to check against the column type list
5069  * provided in the RTE; check_sql_fn_retval can't do that. (If no match,
5070  * we just fail to inline, rather than complaining; see notes for
5071  * tlist_matches_coltypelist.) We don't have to do this for functions
5072  * with declared OUT parameters, even though their funcresulttype is
5073  * RECORDOID, so check get_func_result_type too.
5074  */
5075  if (fexpr->funcresulttype == RECORDOID &&
5076  get_func_result_type(func_oid, NULL, NULL) == TYPEFUNC_RECORD &&
5078  rtfunc->funccoltypes))
5079  goto fail;
5080 
5081  /*
5082  * Looks good --- substitute parameters into the query.
5083  */
5084  querytree = substitute_actual_srf_parameters(querytree,
5085  funcform->pronargs,
5086  fexpr->args);
5087 
5088  /*
5089  * Copy the modified query out of the temporary memory context, and clean
5090  * up.
5091  */
5092  MemoryContextSwitchTo(oldcxt);
5093 
5094  querytree = copyObject(querytree);
5095 
5096  MemoryContextDelete(mycxt);
5097  error_context_stack = sqlerrcontext.previous;
5098  ReleaseSysCache(func_tuple);
5099 
5100  /*
5101  * We don't have to fix collations here because the upper query is already
5102  * parsed, ie, the collations in the RTE are what count.
5103  */
5104 
5105  /*
5106  * Since there is now no trace of the function in the plan tree, we must
5107  * explicitly record the plan's dependency on the function.
5108  */
5109  record_plan_function_dependency(root, func_oid);
5110 
5111  return querytree;
5112 
5113  /* Here if func is not inlinable: release temp memory and return NULL */
5114 fail:
5115  MemoryContextSwitchTo(oldcxt);
5116  MemoryContextDelete(mycxt);
5117  error_context_stack = sqlerrcontext.previous;
5118  ReleaseSysCache(func_tuple);
5119 
5120  return NULL;
5121 }
Oid funcresulttype
Definition: primnodes.h:456
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
List * args
Definition: primnodes.h:463
Oid GetUserId(void)
Definition: miscinit.c:380
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
Definition: functions.c:273
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: nodes.h:525
bool check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, bool *modifyTargetList, JunkFilter **junkFilter)
Definition: functions.c:1574
char get_typtype(Oid typid)
Definition: lsyscache.c:2407
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
bool funcretset
Definition: primnodes.h:457
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:724
bool funcordinality
Definition: parsenodes.h:1041
unsigned int Oid
Definition: postgres_ext.h:31
void(* callback)(void *arg)
Definition: elog.h:254
struct ErrorContextCallback * previous
Definition: elog.h:253
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:762
List * targetList
Definition: parsenodes.h:140
ErrorContextCallback * error_context_stack
Definition: elog.c:88
bool contain_subplans(Node *clause)
Definition: clauses.c:610
#define linitial(l)
Definition: pg_list.h:195
Oid funcid
Definition: primnodes.h:455
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
List * pg_parse_query(const char *query_string)
Definition: postgres.c:632
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
Definition: params.h:108
void check_stack_depth(void)
Definition: postgres.c:3262
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:257
static void sql_inline_error_callback(void *arg)
Definition: clauses.c:4754
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
#define TextDatumGetCString(d)
Definition: builtins.h:84
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition: setrefs.c:2677
static Query * substitute_actual_srf_parameters(Query *expr, int nargs, List *args)
Definition: clauses.c:5130
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
CmdType commandType
Definition: parsenodes.h:112
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:732
List * functions
Definition: parsenodes.h:1040
static int list_length(const List *l)
Definition: pg_list.h:169
List * pg_analyze_and_rewrite_params(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition: postgres.c:717
Datum querytree(PG_FUNCTION_ARGS)
Definition: _int_bool.c:665
RTEKind rtekind
Definition: parsenodes.h:974
static bool tlist_matches_coltypelist(List *tlist, List *coltypelist)
Definition: clauses.c:5198
#define ACL_EXECUTE
Definition: parsenodes.h:81
#define elog(elevel,...)
Definition: elog.h:226
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4655
#define NameStr(name)
Definition: c.h:609
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
Definition: functions.c:184
#define copyObject(obj)
Definition: nodes.h:641
Definition: pg_list.h:50

◆ is_parallel_safe()

bool is_parallel_safe ( PlannerInfo root,
Node node 
)

Definition at line 854 of file clauses.c.

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, PlannerInfo::parent_root, max_parallel_hazard_context::safe_param_ids, and SubPlan::setParam.

Referenced by apply_projection_to_path(), build_join_rel(), create_projection_path(), create_set_projection_path(), create_window_paths(), grouping_planner(), make_grouping_rel(), plan_create_index_workers(), query_planner(), and set_rel_consider_parallel().

855 {
857  PlannerInfo *proot;
858  ListCell *l;
859 
860  /*
861  * Even if the original querytree contained nothing unsafe, we need to
862  * search the expression if we have generated any PARAM_EXEC Params while
863  * planning, because those are parallel-restricted and there might be one
864  * in this expression. But otherwise we don't need to look.
865  */
866  if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
867  root->glob->paramExecTypes == NIL)
868  return true;
869  /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
870  context.max_hazard = PROPARALLEL_SAFE;
871  context.max_interesting = PROPARALLEL_RESTRICTED;
872  context.safe_param_ids = NIL;
873 
874  /*
875  * The params that refer to the same or parent query level are considered
876  * parallel-safe. The idea is that we compute such params at Gather or
877  * Gather Merge node and pass their value to workers.
878  */
879  for (proot = root; proot != NULL; proot = proot->parent_root)
880  {
881  foreach(l, proot->init_plans)
882  {
883  SubPlan *initsubplan = (SubPlan *) lfirst(l);
884 
885  context.safe_param_ids = list_concat(context.safe_param_ids,
886  initsubplan->setParam);
887  }
888  }
889 
890  return !max_parallel_hazard_walker(node, &context);
891 }
char maxParallelHazard
Definition: pathnodes.h:145
#define NIL
Definition: pg_list.h:65
PlannerInfo * parent_root
Definition: pathnodes.h:183
List * list_concat(List *list1, const List *list2)
Definition: list.c:516
List * paramExecTypes
Definition: pathnodes.h:129
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:930
PlannerGlobal * glob
Definition: pathnodes.h:179
List * init_plans
Definition: pathnodes.h:257
#define lfirst(lc)
Definition: pg_list.h:190
List * setParam
Definition: primnodes.h:713

◆ is_pseudo_constant_clause()

bool is_pseudo_constant_clause ( Node clause)

Definition at line 2089 of file clauses.c.

References contain_var_clause(), and contain_volatile_functions().

Referenced by clauselist_selectivity_simple(), and dependency_is_compatible_clause().

2090 {
2091  /*
2092  * We could implement this check in one recursive scan. But since the
2093  * check for volatile functions is both moderately expensive and unlikely
2094  * to fail, it seems better to look for Vars first and only check for
2095  * volatile functions if we find no Vars.
2096  */
2097  if (!contain_var_clause(clause) &&
2098  !contain_volatile_functions(clause))
2099  return true;
2100  return false;
2101 }
bool contain_var_clause(Node *node)
Definition: var.c:331
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:724

◆ is_pseudo_constant_clause_relids()

bool is_pseudo_constant_clause_relids ( Node clause,
Relids  relids 
)

Definition at line 2109 of file clauses.c.

References bms_is_empty(), and contain_volatile_functions().

Referenced by clauselist_selectivity_simple().

2110 {
2111  if (bms_is_empty(relids) &&
2112  !contain_volatile_functions(clause))
2113  return true;
2114  return false;
2115 }
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:724
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:701

◆ max_parallel_hazard()

char max_parallel_hazard ( Query parse)

Definition at line 835 of file clauses.c.

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

836 {
838 
839  context.max_hazard = PROPARALLEL_SAFE;
840  context.max_interesting = PROPARALLEL_UNSAFE;
841  context.safe_param_ids = NIL;
842  (void) max_parallel_hazard_walker((Node *) parse, &context);
843  return context.max_hazard;
844 }
#define NIL
Definition: pg_list.h:65
Definition: nodes.h:525
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:930
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
Definition: regcomp.c:648

◆ NumRelids()

int NumRelids ( Node clause)

Definition at line 2131 of file clauses.c.

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

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

2132 {
2133  Relids varnos = pull_varnos(clause);
2134  int result = bms_num_members(varnos);
2135 
2136  bms_free(varnos);
2137  return result;
2138 }
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
Relids pull_varnos(Node *node)
Definition: var.c:95
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208