PostgreSQL Source Code  git master
clauses.h File Reference
#include "access/htup.h"
#include "nodes/relation.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
 

Macros

#define is_opclause(clause)   ((clause) != NULL && IsA(clause, OpExpr))
 
#define is_funcclause(clause)   ((clause) != NULL && IsA(clause, FuncExpr))
 

Functions

Exprmake_opclause (Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
 
Nodeget_leftop (const Expr *clause)
 
Nodeget_rightop (const Expr *clause)
 
bool not_clause (Node *clause)
 
Exprmake_notclause (Expr *notclause)
 
Exprget_notclausearg (Expr *notclause)
 
bool or_clause (Node *clause)
 
Exprmake_orclause (List *orclauses)
 
bool and_clause (Node *clause)
 
Exprmake_andclause (List *andclauses)
 
Nodemake_and_qual (Node *qual1, Node *qual2)
 
Exprmake_ands_explicit (List *andclauses)
 
Listmake_ands_implicit (Expr *clause)
 
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 (Node *clause)
 
bool contain_subplans (Node *clause)
 
bool contain_mutable_functions (Node *clause)
 
bool contain_volatile_functions (Node *clause)
 
bool contain_volatile_functions_not_nextval (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)
 
void CommuteRowCompareExpr (RowCompareExpr *clause)
 
Nodeeval_const_expressions (PlannerInfo *root, Node *node)
 
Nodeestimate_expression_value (PlannerInfo *root, Node *node)
 
Queryinline_set_returning_function (PlannerInfo *root, RangeTblEntry *rte)
 
Listexpand_function_arguments (List *args, Oid result_type, HeapTuple func_tuple)
 

Macro Definition Documentation

◆ is_funcclause

#define is_funcclause (   clause)    ((clause) != NULL && IsA(clause, FuncExpr))

Definition at line 21 of file clauses.h.

Referenced by boolvarsel(), and clause_is_strict_for().

◆ is_opclause

Function Documentation

◆ and_clause()

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)

Definition at line 2288 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 fix_indexqual_references(), and get_switched_clauses().

2289 {
2290  Oid opoid;
2291  Node *temp;
2292 
2293  /* Sanity checks: caller is at fault if these fail */
2294  if (!is_opclause(clause) ||
2295  list_length(clause->args) != 2)
2296  elog(ERROR, "cannot commute non-binary-operator clause");
2297 
2298  opoid = get_commutator(clause->opno);
2299 
2300  if (!OidIsValid(opoid))
2301  elog(ERROR, "could not find commutator for operator %u",
2302  clause->opno);
2303 
2304  /*
2305  * modify the clause in-place!
2306  */
2307  clause->opno = opoid;
2308  clause->opfuncid = InvalidOid;
2309  /* opresulttype, opretset, opcollid, inputcollid need not change */
2310 
2311  temp = linitial(clause->args);
2312  linitial(clause->args) = lsecond(clause->args);
2313  lsecond(clause->args) = temp;
2314 }
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1298
Definition: nodes.h:517
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define lsecond(l)
Definition: pg_list.h:116
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define is_opclause(clause)
Definition: clauses.h:20
Oid opfuncid
Definition: primnodes.h:498
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:89
Oid opno
Definition: primnodes.h:497
#define elog
Definition: elog.h:219
List * args
Definition: primnodes.h:503

◆ CommuteRowCompareExpr()

void CommuteRowCompareExpr ( RowCompareExpr clause)

Definition at line 2322 of file clauses.c.

References elog, ERROR, get_commutator(), IsA, lappend_oid(), RowCompareExpr::largs, lfirst_oid, NIL, OidIsValid, RowCompareExpr::opnos, RowCompareExpr::rargs, RowCompareExpr::rctype, ROWCOMPARE_GE, ROWCOMPARE_GT, ROWCOMPARE_LE, and ROWCOMPARE_LT.

Referenced by fix_indexqual_references().

2323 {
2324  List *newops;
2325  List *temp;
2326  ListCell *l;
2327 
2328  /* Sanity checks: caller is at fault if these fail */
2329  if (!IsA(clause, RowCompareExpr))
2330  elog(ERROR, "expected a RowCompareExpr");
2331 
2332  /* Build list of commuted operators */
2333  newops = NIL;
2334  foreach(l, clause->opnos)
2335  {
2336  Oid opoid = lfirst_oid(l);
2337 
2338  opoid = get_commutator(opoid);
2339  if (!OidIsValid(opoid))
2340  elog(ERROR, "could not find commutator for operator %u",
2341  lfirst_oid(l));
2342  newops = lappend_oid(newops, opoid);
2343  }
2344 
2345  /*
2346  * modify the clause in-place!
2347  */
2348  switch (clause->rctype)
2349  {
2350  case ROWCOMPARE_LT:
2351  clause->rctype = ROWCOMPARE_GT;
2352  break;
2353  case ROWCOMPARE_LE:
2354  clause->rctype = ROWCOMPARE_GE;
2355  break;
2356  case ROWCOMPARE_GE:
2357  clause->rctype = ROWCOMPARE_LE;
2358  break;
2359  case ROWCOMPARE_GT:
2360  clause->rctype = ROWCOMPARE_LT;
2361  break;
2362  default:
2363  elog(ERROR, "unexpected RowCompare type: %d",
2364  (int) clause->rctype);
2365  break;
2366  }
2367 
2368  clause->opnos = newops;
2369 
2370  /*
2371  * Note: we need not change the opfamilies list; we assume any btree
2372  * opfamily containing an operator will also contain its commutator.
2373  * Collations don't change either.
2374  */
2375 
2376  temp = clause->largs;
2377  clause->largs = clause->rargs;
2378  clause->rargs = temp;
2379 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1298
RowCompareType rctype
Definition: primnodes.h:1039
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:605
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ contain_agg_clause()

bool contain_agg_clause ( Node clause)

Definition at line 418 of file clauses.c.

References contain_agg_clause_walker().

Referenced by get_eclass_for_sort_expr(), and subquery_planner().

419 {
420  return contain_agg_clause_walker(clause, NULL);
421 }
static bool contain_agg_clause_walker(Node *node, void *context)
Definition: clauses.c:424

◆ contain_leaked_vars()

bool contain_leaked_vars ( Node clause)

Definition at line 1516 of file clauses.c.

References contain_leaked_vars_walker().

Referenced by make_restrictinfo_internal(), and qual_is_pushdown_safe().

1517 {
1518  return contain_leaked_vars_walker(clause, NULL);
1519 }
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition: clauses.c:1528

◆ contain_mutable_functions()

bool contain_mutable_functions ( Node clause)

◆ contain_nonstrict_functions()

bool contain_nonstrict_functions ( Node clause)

Definition at line 1315 of file clauses.c.

References contain_nonstrict_functions_walker().

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

1316 {
1317  return contain_nonstrict_functions_walker(clause, NULL);
1318 }
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition: clauses.c:1327

◆ contain_subplans()

bool contain_subplans ( Node clause)

Definition at line 844 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().

845 {
846  return contain_subplans_walker(clause, NULL);
847 }
static bool contain_subplans_walker(Node *node, void *context)
Definition: clauses.c:850

◆ contain_volatile_functions()

◆ contain_volatile_functions_not_nextval()

bool contain_volatile_functions_not_nextval ( Node clause)

Definition at line 1008 of file clauses.c.

References contain_volatile_functions_not_nextval_walker().

Referenced by BeginCopyFrom().

1009 {
1010  return contain_volatile_functions_not_nextval_walker(clause, NULL);
1011 }
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition: clauses.c:1021

◆ contain_window_function()

bool contain_window_function ( Node clause)

Definition at line 728 of file clauses.c.

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr(), and qual_is_pushdown_safe().

729 {
730  return contain_windowfuncs(clause);
731 }
bool contain_windowfuncs(Node *node)
Definition: rewriteManip.c:197

◆ estimate_expression_value()

Node* estimate_expression_value ( PlannerInfo root,
Node node 
)

Definition at line 2493 of file clauses.c.

References eval_const_expressions_context::active_fns, eval_const_expressions_context::boundParams, PlannerGlobal::boundParams, eval_const_expressions_context::case_val, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), PlannerInfo::glob, NIL, and eval_const_expressions_context::root.

Referenced by bernoulli_samplescangetsamplesize(), clause_selectivity(), get_restriction_variable(), gincost_opexpr(), gincost_scalararrayopexpr(), preprocess_limit(), scalararraysel(), system_rows_samplescangetsamplesize(), system_samplescangetsamplesize(), and system_time_samplescangetsamplesize().

2494 {
2496 
2497  context.boundParams = root->glob->boundParams; /* bound Params */
2498  /* we do not need to mark the plan as depending on inlined functions */
2499  context.root = NULL;
2500  context.active_fns = NIL; /* nothing being recursively simplified */
2501  context.case_val = NULL; /* no CASE being examined */
2502  context.estimate = true; /* unsafe transformations OK */
2503  return eval_const_expressions_mutator(node, &context);
2504 }
#define NIL
Definition: pg_list.h:69
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition: clauses.c:2538
ParamListInfo boundParams
Definition: clauses.c:65
PlannerGlobal * glob
Definition: relation.h:171
ParamListInfo boundParams
Definition: relation.h:110

◆ eval_const_expressions()

Node* eval_const_expressions ( PlannerInfo root,
Node node 
)

Definition at line 2460 of file clauses.c.

References eval_const_expressions_context::active_fns, eval_const_expressions_context::boundParams, PlannerGlobal::boundParams, eval_const_expressions_context::case_val, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), PlannerInfo::glob, NIL, and eval_const_expressions_context::root.

Referenced by ATExecAttachPartition(), convert_EXISTS_to_ANY(), expression_planner(), get_proposed_default_constraint(), get_relation_constraints(), inline_set_returning_function(), PartConstraintImpliedByRelConstraint(), preprocess_expression(), process_implied_equality(), RelationBuildPartitionKey(), RelationGetIndexExpressions(), RelationGetIndexPredicate(), set_append_rel_size(), and simplify_EXISTS_query().

2461 {
2463 
2464  if (root)
2465  context.boundParams = root->glob->boundParams; /* bound Params */
2466  else
2467  context.boundParams = NULL;
2468  context.root = root; /* for inlined-function dependencies */
2469  context.active_fns = NIL; /* nothing being recursively simplified */
2470  context.case_val = NULL; /* no CASE being examined */
2471  context.estimate = false; /* safe transformations only */
2472  return eval_const_expressions_mutator(node, &context);
2473 }
#define NIL
Definition: pg_list.h:69
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition: clauses.c:2538
ParamListInfo boundParams
Definition: clauses.c:65
PlannerGlobal * glob
Definition: relation.h:171
ParamListInfo boundParams
Definition: relation.h:110

◆ expand_function_arguments()

List* expand_function_arguments ( List args,
Oid  result_type,
HeapTuple  func_tuple 
)

Definition at line 4114 of file clauses.c.

References add_function_defaults(), arg, generate_unaccent_rules::args, GETSTRUCT, IsA, lfirst, list_length(), recheck_cast_function_args(), and reorder_function_arguments().

Referenced by eval_const_expressions_mutator(), ExecuteCallStmt(), and simplify_function().

4115 {
4116  Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
4117  bool has_named_args = false;
4118  ListCell *lc;
4119 
4120  /* Do we have any named arguments? */
4121  foreach(lc, args)
4122  {
4123  Node *arg = (Node *) lfirst(lc);
4124 
4125  if (IsA(arg, NamedArgExpr))
4126  {
4127  has_named_args = true;
4128  break;
4129  }
4130  }
4131 
4132  /* If so, we must apply reorder_function_arguments */
4133  if (has_named_args)
4134  {
4135  args = reorder_function_arguments(args, func_tuple);
4136  /* Recheck argument types and add casts if needed */
4137  recheck_cast_function_args(args, result_type, func_tuple);
4138  }
4139  else if (list_length(args) < funcform->pronargs)
4140  {
4141  /* No named args, but we seem to be short some defaults */
4142  args = add_function_defaults(args, func_tuple);
4143  /* Recheck argument types and add casts if needed */
4144  recheck_cast_function_args(args, result_type, func_tuple);
4145  }
4146 
4147  return args;
4148 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Definition: nodes.h:517
static void recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple)
Definition: clauses.c:4287
static List * add_function_defaults(List *args, HeapTuple func_tuple)
Definition: clauses.c:4227
static List * reorder_function_arguments(List *args, HeapTuple func_tuple)
Definition: clauses.c:4157
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:132
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
void * arg

◆ expression_returns_set_rows()

double expression_returns_set_rows ( Node clause)

Definition at line 803 of file clauses.c.

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

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

804 {
805  if (clause == NULL)
806  return 1.0;
807  if (IsA(clause, FuncExpr))
808  {
809  FuncExpr *expr = (FuncExpr *) clause;
810 
811  if (expr->funcretset)
812  return clamp_row_est(get_func_rows(expr->funcid));
813  }
814  if (IsA(clause, OpExpr))
815  {
816  OpExpr *expr = (OpExpr *) clause;
817 
818  if (expr->opretset)
819  {
820  set_opfuncid(expr);
821  return clamp_row_est(get_func_rows(expr->opfuncid));
822  }
823  }
824  return 1.0;
825 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
float4 get_func_rows(Oid funcid)
Definition: lsyscache.c:1664
bool funcretset
Definition: primnodes.h:452
Oid funcid
Definition: primnodes.h:450
Oid opfuncid
Definition: primnodes.h:498
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1613
double clamp_row_est(double nrows)
Definition: costsize.c:188
bool opretset
Definition: primnodes.h:500

◆ find_forced_null_var()

Var* find_forced_null_var ( Node clause)

Definition at line 2121 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().

2122 {
2123  if (node == NULL)
2124  return NULL;
2125  if (IsA(node, NullTest))
2126  {
2127  /* check for var IS NULL */
2128  NullTest *expr = (NullTest *) node;
2129 
2130  if (expr->nulltesttype == IS_NULL && !expr->argisrow)
2131  {
2132  Var *var = (Var *) expr->arg;
2133 
2134  if (var && IsA(var, Var) &&
2135  var->varlevelsup == 0)
2136  return var;
2137  }
2138  }
2139  else if (IsA(node, BooleanTest))
2140  {
2141  /* var IS UNKNOWN is equivalent to var IS NULL */
2142  BooleanTest *expr = (BooleanTest *) node;
2143 
2144  if (expr->booltesttype == IS_UNKNOWN)
2145  {
2146  Var *var = (Var *) expr->arg;
2147 
2148  if (var && IsA(var, Var) &&
2149  var->varlevelsup == 0)
2150  return var;
2151  }
2152  }
2153  return NULL;
2154 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Index varlevelsup
Definition: primnodes.h:174
Definition: primnodes.h:164
Expr * arg
Definition: primnodes.h:1188
Expr * arg
Definition: primnodes.h:1211
BoolTestType booltesttype
Definition: primnodes.h:1212
NullTestType nulltesttype
Definition: primnodes.h:1189
bool argisrow
Definition: primnodes.h:1190

◆ find_forced_null_vars()

List* find_forced_null_vars ( Node clause)

Definition at line 2062 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().

2063 {
2064  List *result = NIL;
2065  Var *var;
2066  ListCell *l;
2067 
2068  if (node == NULL)
2069  return NIL;
2070  /* Check single-clause cases using subroutine */
2071  var = find_forced_null_var(node);
2072  if (var)
2073  {
2074  result = list_make1(var);
2075  }
2076  /* Otherwise, handle AND-conditions */
2077  else if (IsA(node, List))
2078  {
2079  /*
2080  * At top level, we are examining an implicit-AND list: if any of the
2081  * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
2082  */
2083  foreach(l, (List *) node)
2084  {
2085  result = list_concat(result,
2087  }
2088  }
2089  else if (IsA(node, BoolExpr))
2090  {
2091  BoolExpr *expr = (BoolExpr *) node;
2092 
2093  /*
2094  * We don't bother considering the OR case, because it's fairly
2095  * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
2096  * the NOT case isn't worth expending code on.
2097  */
2098  if (expr->boolop == AND_EXPR)
2099  {
2100  /* At top level we can just recurse (to the List case) */
2101  result = find_forced_null_vars((Node *) expr->args);
2102  }
2103  }
2104  return result;
2105 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Definition: nodes.h:517
List * list_concat(List *list1, List *list2)
Definition: list.c:321
Definition: primnodes.h:164
List * find_forced_null_vars(Node *node)
Definition: clauses.c:2062
#define list_make1(x1)
Definition: pg_list.h:139
BoolExprType boolop
Definition: primnodes.h:563
#define lfirst(lc)
Definition: pg_list.h:106
List * args
Definition: primnodes.h:564
Definition: pg_list.h:45
Var * find_forced_null_var(Node *node)
Definition: clauses.c:2121

◆ find_nonnullable_rels()

Relids find_nonnullable_rels ( Node clause)

Definition at line 1661 of file clauses.c.

References find_nonnullable_rels_walker().

Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().

1662 {
1663  return find_nonnullable_rels_walker(clause, true);
1664 }
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition: clauses.c:1667

◆ find_nonnullable_vars()

List* find_nonnullable_vars ( Node clause)

Definition at line 1869 of file clauses.c.

References find_nonnullable_vars_walker().

Referenced by reduce_outer_joins_pass2().

1870 {
1871  return find_nonnullable_vars_walker(clause, true);
1872 }
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition: clauses.c:1875

◆ find_window_functions()

WindowFuncLists* find_window_functions ( Node clause,
Index  maxWinRef 
)

Definition at line 741 of file clauses.c.

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

Referenced by grouping_planner().

742 {
743  WindowFuncLists *lists = palloc(sizeof(WindowFuncLists));
744 
745  lists->numWindowFuncs = 0;
746  lists->maxWinRef = maxWinRef;
747  lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
748  (void) find_window_functions_walker(clause, lists);
749  return lists;
750 }
Index maxWinRef
Definition: clauses.h:26
int numWindowFuncs
Definition: clauses.h:25
void * palloc0(Size size)
Definition: mcxt.c:955
void * palloc(Size size)
Definition: mcxt.c:924
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition: clauses.c:753
Definition: pg_list.h:45
List ** windowFuncs
Definition: clauses.h:27

◆ get_agg_clause_costs()

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

Definition at line 468 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().

470 {
472 
473  context.root = root;
474  context.aggsplit = aggsplit;
475  context.costs = costs;
476  (void) get_agg_clause_costs_walker(clause, &context);
477 }
AggClauseCosts * costs
Definition: clauses.c:60
static bool get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context)
Definition: clauses.c:480

◆ get_leftop()

◆ get_notclausearg()

◆ get_rightop()

◆ inline_set_returning_function()

Query* inline_set_returning_function ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 4932 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, eval_const_expressions(), FmgrHookIsNeeded, RangeTblFunction::funccoltypes, RangeTblFunction::funcexpr, FuncExpr::funcid, RangeTblEntry::funcordinality, FuncExpr::funcretset, RangeTblEntry::functions, get_func_result_type(), get_typtype(), GETSTRUCT, GetUserId(), PlannerInfo::glob, heap_attisnull(), HeapTupleIsValid, PlannerGlobal::invalItems, IsA, linitial, list_concat(), list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, NIL, 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 inline_set_returning_functions().

4933 {
4934  RangeTblFunction *rtfunc;
4935  FuncExpr *fexpr;
4936  Oid func_oid;
4937  HeapTuple func_tuple;
4938  Form_pg_proc funcform;
4939  char *src;
4940  Datum tmp;
4941  bool isNull;
4942  bool modifyTargetList;
4943  MemoryContext oldcxt;
4944  MemoryContext mycxt;
4945  List *saveInvalItems;
4946  inline_error_callback_arg callback_arg;
4947  ErrorContextCallback sqlerrcontext;
4949  List *raw_parsetree_list;
4950  List *querytree_list;
4951  Query *querytree;
4952 
4953  Assert(rte->rtekind == RTE_FUNCTION);
4954 
4955  /*
4956  * It doesn't make a lot of sense for a SQL SRF to refer to itself in its
4957  * own FROM clause, since that must cause infinite recursion at runtime.
4958  * It will cause this code to recurse too, so check for stack overflow.
4959  * (There's no need to do more.)
4960  */
4962 
4963  /* Fail if the RTE has ORDINALITY - we don't implement that here. */
4964  if (rte->funcordinality)
4965  return NULL;
4966 
4967  /* Fail if RTE isn't a single, simple FuncExpr */
4968  if (list_length(rte->functions) != 1)
4969  return NULL;
4970  rtfunc = (RangeTblFunction *) linitial(rte->functions);
4971 
4972  if (!IsA(rtfunc->funcexpr, FuncExpr))
4973  return NULL;
4974  fexpr = (FuncExpr *) rtfunc->funcexpr;
4975 
4976  func_oid = fexpr->funcid;
4977 
4978  /*
4979  * The function must be declared to return a set, else inlining would
4980  * change the results if the contained SELECT didn't return exactly one
4981  * row.
4982  */
4983  if (!fexpr->funcretset)
4984  return NULL;
4985 
4986  /*
4987  * Refuse to inline if the arguments contain any volatile functions or
4988  * sub-selects. Volatile functions are rejected because inlining may
4989  * result in the arguments being evaluated multiple times, risking a
4990  * change in behavior. Sub-selects are rejected partly for implementation
4991  * reasons (pushing them down another level might change their behavior)
4992  * and partly because they're likely to be expensive and so multiple
4993  * evaluation would be bad.
4994  */
4995  if (contain_volatile_functions((Node *) fexpr->args) ||
4996  contain_subplans((Node *) fexpr->args))
4997  return NULL;
4998 
4999  /* Check permission to call function (fail later, if not) */
5000  if (pg_proc_aclcheck(func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
5001  return NULL;
5002 
5003  /* Check whether a plugin wants to hook function entry/exit */
5004  if (FmgrHookIsNeeded(func_oid))
5005  return NULL;
5006 
5007  /*
5008  * OK, let's take a look at the function's pg_proc entry.
5009  */
5010  func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid));
5011  if (!HeapTupleIsValid(func_tuple))
5012  elog(ERROR, "cache lookup failed for function %u", func_oid);
5013  funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
5014 
5015  /*
5016  * Forget it if the function is not SQL-language or has other showstopper
5017  * properties. In particular it mustn't be declared STRICT, since we
5018  * couldn't enforce that. It also mustn't be VOLATILE, because that is
5019  * supposed to cause it to be executed with its own snapshot, rather than
5020  * sharing the snapshot of the calling query. We also disallow returning
5021  * SETOF VOID, because inlining would result in exposing the actual result
5022  * of the function's last SELECT, which should not happen in that case.
5023  * (Rechecking prokind and proretset is just paranoia.)
5024  */
5025  if (funcform->prolang != SQLlanguageId ||
5026  funcform->prokind != PROKIND_FUNCTION ||
5027  funcform->proisstrict ||
5028  funcform->provolatile == PROVOLATILE_VOLATILE ||
5029  funcform->prorettype == VOIDOID ||
5030  funcform->prosecdef ||
5031  !funcform->proretset ||
5032  !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL))
5033  {
5034  ReleaseSysCache(func_tuple);
5035  return NULL;
5036  }
5037 
5038  /*
5039  * Make a temporary memory context, so that we don't leak all the stuff
5040  * that parsing might create.
5041  */
5043  "inline_set_returning_function",
5045  oldcxt = MemoryContextSwitchTo(mycxt);
5046 
5047  /*
5048  * When we call eval_const_expressions below, it might try to add items to
5049  * root->glob->invalItems. Since it is running in the temp context, those
5050  * items will be in that context, and will need to be copied out if we're
5051  * successful. Temporarily reset the list so that we can keep those items
5052  * separate from the pre-existing list contents.
5053  */
5054  saveInvalItems = root->glob->invalItems;
5055  root->glob->invalItems = NIL;
5056 
5057  /* Fetch the function body */
5058  tmp = SysCacheGetAttr(PROCOID,
5059  func_tuple,
5060  Anum_pg_proc_prosrc,
5061  &isNull);
5062  if (isNull)
5063  elog(ERROR, "null prosrc for function %u", func_oid);
5064  src = TextDatumGetCString(tmp);
5065 
5066  /*
5067  * Setup error traceback support for ereport(). This is so that we can
5068  * finger the function that bad information came from.
5069  */
5070  callback_arg.proname = NameStr(funcform->proname);
5071  callback_arg.prosrc = src;
5072 
5073  sqlerrcontext.callback = sql_inline_error_callback;
5074  sqlerrcontext.arg = (void *) &callback_arg;
5075  sqlerrcontext.previous = error_context_stack;
5076  error_context_stack = &sqlerrcontext;
5077 
5078  /*
5079  * Run eval_const_expressions on the function call. This is necessary to
5080  * ensure that named-argument notation is converted to positional notation
5081  * and any default arguments are inserted. It's a bit of overkill for the
5082  * arguments, since they'll get processed again later, but no harm will be
5083  * done.
5084  */
5085  fexpr = (FuncExpr *) eval_const_expressions(root, (Node *) fexpr);
5086 
5087  /* It should still be a call of the same function, but let's check */
5088  if (!IsA(fexpr, FuncExpr) ||
5089  fexpr->funcid != func_oid)
5090  goto fail;
5091 
5092  /* Arg list length should now match the function */
5093  if (list_length(fexpr->args) != funcform->pronargs)
5094  goto fail;
5095 
5096  /*
5097  * Set up to handle parameters while parsing the function body. We can
5098  * use the FuncExpr just created as the input for
5099  * prepare_sql_fn_parse_info.
5100  */
5101  pinfo = prepare_sql_fn_parse_info(func_tuple,
5102  (Node *) fexpr,
5103  fexpr->inputcollid);
5104 
5105  /*
5106  * Parse, analyze, and rewrite (unlike inline_function(), we can't skip
5107  * rewriting here). We can fail as soon as we find more than one query,
5108  * though.
5109  */
5110  raw_parsetree_list = pg_parse_query(src);
5111  if (list_length(raw_parsetree_list) != 1)
5112  goto fail;
5113 
5114  querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list),
5115  src,
5117  pinfo, NULL);
5118  if (list_length(querytree_list) != 1)
5119  goto fail;
5120  querytree = linitial(querytree_list);
5121 
5122  /*
5123  * The single command must be a plain SELECT.
5124  */
5125  if (!IsA(querytree, Query) ||
5126  querytree->commandType != CMD_SELECT)
5127  goto fail;
5128 
5129  /*
5130  * Make sure the function (still) returns what it's declared to. This
5131  * will raise an error if wrong, but that's okay since the function would
5132  * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5133  * RelabelType(s) and/or NULL columns if needed to make the tlist
5134  * expression(s) match the declared type of the function.
5135  *
5136  * If the function returns a composite type, don't inline unless the check
5137  * shows it's returning a whole tuple result; otherwise what it's
5138  * returning is a single composite column which is not what we need. (Like
5139  * check_sql_fn_retval, we deliberately exclude domains over composite
5140  * here.)
5141  */
5142  if (!check_sql_fn_retval(func_oid, fexpr->funcresulttype,
5143  querytree_list,
5144  &modifyTargetList, NULL) &&
5145  (get_typtype(fexpr->funcresulttype) == TYPTYPE_COMPOSITE ||
5146  fexpr->funcresulttype == RECORDOID))
5147  goto fail; /* reject not-whole-tuple-result cases */
5148 
5149  /*
5150  * If we had to modify the tlist to make it match, and the statement is
5151  * one in which changing the tlist contents could change semantics, we
5152  * have to punt and not inline.
5153  */
5154  if (modifyTargetList)
5155  goto fail;
5156 
5157  /*
5158  * If it returns RECORD, we have to check against the column type list
5159  * provided in the RTE; check_sql_fn_retval can't do that. (If no match,
5160  * we just fail to inline, rather than complaining; see notes for
5161  * tlist_matches_coltypelist.) We don't have to do this for functions
5162  * with declared OUT parameters, even though their funcresulttype is
5163  * RECORDOID, so check get_func_result_type too.
5164  */
5165  if (fexpr->funcresulttype == RECORDOID &&
5166  get_func_result_type(func_oid, NULL, NULL) == TYPEFUNC_RECORD &&
5168  rtfunc->funccoltypes))
5169  goto fail;
5170 
5171  /*
5172  * Looks good --- substitute parameters into the query.
5173  */
5174  querytree = substitute_actual_srf_parameters(querytree,
5175  funcform->pronargs,
5176  fexpr->args);
5177 
5178  /*
5179  * Copy the modified query out of the temporary memory context, and clean
5180  * up.
5181  */
5182  MemoryContextSwitchTo(oldcxt);
5183 
5184  querytree = copyObject(querytree);
5185 
5186  /* copy up any new invalItems, too */
5187  root->glob->invalItems = list_concat(saveInvalItems,
5188  copyObject(root->glob->invalItems));
5189 
5190  MemoryContextDelete(mycxt);
5191  error_context_stack = sqlerrcontext.previous;
5192  ReleaseSysCache(func_tuple);
5193 
5194  /*
5195  * We don't have to fix collations here because the upper query is already
5196  * parsed, ie, the collations in the RTE are what count.
5197  */
5198 
5199  /*
5200  * Since there is now no trace of the function in the plan tree, we must
5201  * explicitly record the plan's dependency on the function.
5202  */
5203  record_plan_function_dependency(root, func_oid);
5204 
5205  return querytree;
5206 
5207  /* Here if func is not inlinable: release temp memory and return NULL */
5208 fail:
5209  MemoryContextSwitchTo(oldcxt);
5210  root->glob->invalItems = saveInvalItems;
5211  MemoryContextDelete(mycxt);
5212  error_context_stack = sqlerrcontext.previous;
5213  ReleaseSysCache(func_tuple);
5214 
5215  return NULL;
5216 }
Oid funcresulttype
Definition: primnodes.h:451
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
List * args
Definition: primnodes.h:458
Oid GetUserId(void)
Definition: miscinit.c:379
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:517
bool check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, bool *modifyTargetList, JunkFilter **junkFilter)
Definition: functions.c:1586
char get_typtype(Oid typid)
Definition: lsyscache.c:2383
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2460
List * list_concat(List *list1, List *list2)
Definition: list.c:321
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:397
bool funcretset
Definition: primnodes.h:452
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:958
bool funcordinality
Definition: parsenodes.h:1017
unsigned int Oid
Definition: postgres_ext.h:31
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:735
List * targetList
Definition: parsenodes.h:140
ErrorContextCallback * error_context_stack
Definition: elog.c:88
bool contain_subplans(Node *clause)
Definition: clauses.c:844
#define linitial(l)
Definition: pg_list.h:111
Oid funcid
Definition: primnodes.h:450
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
List * pg_parse_query(const char *query_string)
Definition: postgres.c:609
#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:3159
PlannerGlobal * glob
Definition: relation.h:171
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:272
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170
static void sql_inline_error_callback(void *arg)
Definition: clauses.c:4820
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
List * invalItems
Definition: relation.h:129
#define TextDatumGetCString(d)
Definition: builtins.h:96
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition: setrefs.c:2558
static Query * substitute_actual_srf_parameters(Query *expr, int nargs, List *args)
Definition: clauses.c:5225
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:132
CmdType commandType
Definition: parsenodes.h:112
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:699
List * functions
Definition: parsenodes.h:1016
static int list_length(const List *l)
Definition: pg_list.h:89
List * pg_analyze_and_rewrite_params(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition: postgres.c:688
Datum querytree(PG_FUNCTION_ARGS)
Definition: _int_bool.c:665
RTEKind rtekind
Definition: parsenodes.h:962
static bool tlist_matches_coltypelist(List *tlist, List *coltypelist)
Definition: clauses.c:5293
#define ACL_EXECUTE
Definition: parsenodes.h:81
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4651
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
Definition: functions.c:184
#define copyObject(obj)
Definition: nodes.h:630
Definition: pg_list.h:45

◆ is_parallel_safe()

bool is_parallel_safe ( PlannerInfo root,
Node node 
)

Definition at line 1088 of file clauses.c.

References PlannerInfo::glob, PlannerInfo::init_plans, lcons_int(), lfirst, lfirst_int, 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().

1089 {
1091  PlannerInfo *proot;
1092  ListCell *l;
1093 
1094  /*
1095  * Even if the original querytree contained nothing unsafe, we need to
1096  * search the expression if we have generated any PARAM_EXEC Params while
1097  * planning, because those are parallel-restricted and there might be one
1098  * in this expression. But otherwise we don't need to look.
1099  */
1100  if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
1101  root->glob->paramExecTypes == NIL)
1102  return true;
1103  /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
1104  context.max_hazard = PROPARALLEL_SAFE;
1105  context.max_interesting = PROPARALLEL_RESTRICTED;
1106  context.safe_param_ids = NIL;
1107 
1108  /*
1109  * The params that refer to the same or parent query level are considered
1110  * parallel-safe. The idea is that we compute such params at Gather or
1111  * Gather Merge node and pass their value to workers.
1112  */
1113  for (proot = root; proot != NULL; proot = proot->parent_root)
1114  {
1115  foreach(l, proot->init_plans)
1116  {
1117  SubPlan *initsubplan = (SubPlan *) lfirst(l);
1118  ListCell *l2;
1119 
1120  foreach(l2, initsubplan->setParam)
1121  context.safe_param_ids = lcons_int(lfirst_int(l2),
1122  context.safe_param_ids);
1123  }
1124  }
1125 
1126  return !max_parallel_hazard_walker(node, &context);
1127 }
char maxParallelHazard
Definition: relation.h:147
#define NIL
Definition: pg_list.h:69
List * lcons_int(int datum, List *list)
Definition: list.c:277
List * paramExecTypes
Definition: relation.h:131
#define lfirst_int(lc)
Definition: pg_list.h:107
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:1166
PlannerGlobal * glob
Definition: relation.h:171
struct PlannerInfo * parent_root
Definition: relation.h:175
List * init_plans
Definition: relation.h:242
#define lfirst(lc)
Definition: pg_list.h:106
List * setParam
Definition: primnodes.h:708

◆ is_pseudo_constant_clause()

bool is_pseudo_constant_clause ( Node clause)

Definition at line 2231 of file clauses.c.

References contain_var_clause(), and contain_volatile_functions().

Referenced by clauselist_selectivity(), dependency_is_compatible_clause(), IsTidEqualAnyClause(), and IsTidEqualClause().

2232 {
2233  /*
2234  * We could implement this check in one recursive scan. But since the
2235  * check for volatile functions is both moderately expensive and unlikely
2236  * to fail, it seems better to look for Vars first and only check for
2237  * volatile functions if we find no Vars.
2238  */
2239  if (!contain_var_clause(clause) &&
2240  !contain_volatile_functions(clause))
2241  return true;
2242  return false;
2243 }
bool contain_var_clause(Node *node)
Definition: var.c:331
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:958

◆ is_pseudo_constant_clause_relids()

bool is_pseudo_constant_clause_relids ( Node clause,
Relids  relids 
)

Definition at line 2251 of file clauses.c.

References bms_is_empty(), and contain_volatile_functions().

Referenced by clauselist_selectivity().

2252 {
2253  if (bms_is_empty(relids) &&
2254  !contain_volatile_functions(clause))
2255  return true;
2256  return false;
2257 }
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:958
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:729

◆ make_and_qual()

Node* make_and_qual ( Node qual1,
Node qual2 
)

Definition at line 349 of file clauses.c.

References list_make2, and make_andclause().

Referenced by AddQual(), and subquery_push_qual().

350 {
351  if (qual1 == NULL)
352  return qual2;
353  if (qual2 == NULL)
354  return qual1;
355  return (Node *) make_andclause(list_make2(qual1, qual2));
356 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
Definition: nodes.h:517
Expr * make_andclause(List *andclauses)
Definition: clauses.c:328

◆ make_andclause()

Expr* make_andclause ( List andclauses)

Definition at line 328 of file clauses.c.

References AND_EXPR, BoolExpr::args, BoolExpr::boolop, BoolExpr::location, and makeNode.

Referenced by eval_const_expressions_mutator(), find_duplicate_ors(), make_and_qual(), make_ands_explicit(), make_sub_restrictinfos(), negate_clause(), process_duplicate_ors(), process_sublinks_mutator(), and pull_up_sublinks_qual_recurse().

329 {
330  BoolExpr *expr = makeNode(BoolExpr);
331 
332  expr->boolop = AND_EXPR;
333  expr->args = andclauses;
334  expr->location = -1;
335  return (Expr *) expr;
336 }
int location
Definition: primnodes.h:565
BoolExprType boolop
Definition: primnodes.h:563
#define makeNode(_type_)
Definition: nodes.h:565
List * args
Definition: primnodes.h:564

◆ make_ands_explicit()

Expr* make_ands_explicit ( List andclauses)

Definition at line 368 of file clauses.c.

References linitial, list_length(), make_andclause(), makeBoolConst(), and NIL.

Referenced by ATExecAttachPartition(), convert_EXISTS_to_ANY(), create_bitmap_subplan(), ExecInitCheck(), extract_or_clause(), get_proposed_default_constraint(), get_qual_for_list(), show_qual(), and UpdateIndexRelation().

369 {
370  if (andclauses == NIL)
371  return (Expr *) makeBoolConst(true, false);
372  else if (list_length(andclauses) == 1)
373  return (Expr *) linitial(andclauses);
374  else
375  return make_andclause(andclauses);
376 }
#define NIL
Definition: pg_list.h:69
#define linitial(l)
Definition: pg_list.h:111
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:356
static int list_length(const List *l)
Definition: pg_list.h:89
Expr * make_andclause(List *andclauses)
Definition: clauses.c:328

◆ make_ands_implicit()

List* make_ands_implicit ( Expr clause)

Definition at line 379 of file clauses.c.

References and_clause(), DatumGetBool, IsA, list_make1, and NIL.

Referenced by convert_EXISTS_to_ANY(), cost_subplan(), DefineIndex(), get_proposed_default_constraint(), get_relation_constraints(), PartConstraintImpliedByRelConstraint(), preprocess_expression(), RelationGetIndexPredicate(), set_append_rel_size(), test_predtest(), and TriggerEnabled().

380 {
381  /*
382  * NB: because the parser sets the qual field to NULL in a query that has
383  * no WHERE clause, we must consider a NULL input clause as TRUE, even
384  * though one might more reasonably think it FALSE. Grumble. If this
385  * causes trouble, consider changing the parser's behavior.
386  */
387  if (clause == NULL)
388  return NIL; /* NULL -> NIL list == TRUE */
389  else if (and_clause((Node *) clause))
390  return ((BoolExpr *) clause)->args;
391  else if (IsA(clause, Const) &&
392  !((Const *) clause)->constisnull &&
393  DatumGetBool(((Const *) clause)->constvalue))
394  return NIL; /* constant TRUE input -> NIL list */
395  else
396  return list_make1(clause);
397 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Definition: nodes.h:517
#define list_make1(x1)
Definition: pg_list.h:139
bool and_clause(Node *clause)
Definition: clauses.c:315
#define DatumGetBool(X)
Definition: postgres.h:378

◆ make_notclause()

Expr* make_notclause ( Expr notclause)

Definition at line 250 of file clauses.c.

References BoolExpr::args, BoolExpr::boolop, list_make1, BoolExpr::location, makeNode, and NOT_EXPR.

Referenced by negate_clause().

251 {
252  BoolExpr *expr = makeNode(BoolExpr);
253 
254  expr->boolop = NOT_EXPR;
255  expr->args = list_make1(notclause);
256  expr->location = -1;
257  return (Expr *) expr;
258 }
int location
Definition: primnodes.h:565
#define list_make1(x1)
Definition: pg_list.h:139
BoolExprType boolop
Definition: primnodes.h:563
#define makeNode(_type_)
Definition: nodes.h:565
List * args
Definition: primnodes.h:564

◆ make_opclause()

Expr* make_opclause ( Oid  opno,
Oid  opresulttype,
bool  opretset,
Expr leftop,
Expr rightop,
Oid  opcollid,
Oid  inputcollid 
)

Definition at line 173 of file clauses.c.

References OpExpr::args, OpExpr::inputcollid, InvalidOid, list_make1, list_make2, OpExpr::location, makeNode, OpExpr::opcollid, OpExpr::opfuncid, OpExpr::opno, OpExpr::opresulttype, and OpExpr::opretset.

Referenced by adjust_rowcompare_for_index(), build_implied_join_equality(), convert_EXISTS_to_ANY(), expand_boolean_index_clause(), make_partition_op_expr(), match_clause_to_partition_key(), network_prefix_quals(), operator_predicate_proof(), prefix_quals(), and process_implied_equality().

176 {
177  OpExpr *expr = makeNode(OpExpr);
178 
179  expr->opno = opno;
180  expr->opfuncid = InvalidOid;
181  expr->opresulttype = opresulttype;
182  expr->opretset = opretset;
183  expr->opcollid = opcollid;
184  expr->inputcollid = inputcollid;
185  if (rightop)
186  expr->args = list_make2(leftop, rightop);
187  else
188  expr->args = list_make1(leftop);
189  expr->location = -1;
190  return (Expr *) expr;
191 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
#define list_make1(x1)
Definition: pg_list.h:139
Oid opresulttype
Definition: primnodes.h:499
int location
Definition: primnodes.h:504
Oid opcollid
Definition: primnodes.h:501
Oid opfuncid
Definition: primnodes.h:498
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:565
Oid inputcollid
Definition: primnodes.h:502
Oid opno
Definition: primnodes.h:497
List * args
Definition: primnodes.h:503
bool opretset
Definition: primnodes.h:500

◆ make_orclause()

Expr* make_orclause ( List orclauses)

Definition at line 294 of file clauses.c.

References BoolExpr::args, BoolExpr::boolop, BoolExpr::location, makeNode, and OR_EXPR.

Referenced by create_bitmap_subplan(), create_tidscan_plan(), eval_const_expressions_mutator(), ExplainNode(), extract_or_clause(), make_sub_restrictinfos(), negate_clause(), process_duplicate_ors(), and process_sublinks_mutator().

295 {
296  BoolExpr *expr = makeNode(BoolExpr);
297 
298  expr->boolop = OR_EXPR;
299  expr->args = orclauses;
300  expr->location = -1;
301  return (Expr *) expr;
302 }
int location
Definition: primnodes.h:565
BoolExprType boolop
Definition: primnodes.h:563
#define makeNode(_type_)
Definition: nodes.h:565
List * args
Definition: primnodes.h:564

◆ max_parallel_hazard()

char max_parallel_hazard ( Query parse)

Definition at line 1069 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().

1070 {
1072 
1073  context.max_hazard = PROPARALLEL_SAFE;
1074  context.max_interesting = PROPARALLEL_UNSAFE;
1075  context.safe_param_ids = NIL;
1076  (void) max_parallel_hazard_walker((Node *) parse, &context);
1077  return context.max_hazard;
1078 }
#define NIL
Definition: pg_list.h:69
Definition: nodes.h:517
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:1166
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
Definition: regcomp.c:649

◆ not_clause()

bool not_clause ( Node clause)

Definition at line 237 of file clauses.c.

References boolop(), IsA, and NOT_EXPR.

Referenced by clause_selectivity(), dependency_is_compatible_clause(), expand_boolean_index_clause(), match_boolean_index_clause(), match_boolean_partition_clause(), and pull_up_sublinks_qual_recurse().

238 {
239  return (clause != NULL &&
240  IsA(clause, BoolExpr) &&
241  ((BoolExpr *) clause)->boolop == NOT_EXPR);
242 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:420
#define IsA(nodeptr, _type_)
Definition: nodes.h:568

◆ NumRelids()

int NumRelids ( Node clause)

Definition at line 2273 of file clauses.c.

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

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

2274 {
2275  Relids varnos = pull_varnos(clause);
2276  int result = bms_num_members(varnos);
2277 
2278  bms_free(varnos);
2279  return result;
2280 }
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:671
Relids pull_varnos(Node *node)
Definition: var.c:95
void bms_free(Bitmapset *a)
Definition: bitmapset.c:267

◆ or_clause()

bool or_clause ( Node clause)

Definition at line 281 of file clauses.c.

References boolop(), IsA, and OR_EXPR.

Referenced by clause_selectivity(), extract_or_clause(), find_duplicate_ors(), gen_partprune_steps_internal(), make_restrictinfo(), make_sub_restrictinfos(), predicate_classify(), process_sublinks_mutator(), pull_ors(), simplify_or_arguments(), and TidQualFromExpr().

282 {
283  return (clause != NULL &&
284  IsA(clause, BoolExpr) &&
285  ((BoolExpr *) clause)->boolop == OR_EXPR);
286 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:420
#define IsA(nodeptr, _type_)
Definition: nodes.h:568