PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
clauses.h File Reference
#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)
 

Macro Definition Documentation

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

Function Documentation

bool and_clause ( Node clause)
void CommuteOpExpr ( OpExpr clause)

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

2254 {
2255  Oid opoid;
2256  Node *temp;
2257 
2258  /* Sanity checks: caller is at fault if these fail */
2259  if (!is_opclause(clause) ||
2260  list_length(clause->args) != 2)
2261  elog(ERROR, "cannot commute non-binary-operator clause");
2262 
2263  opoid = get_commutator(clause->opno);
2264 
2265  if (!OidIsValid(opoid))
2266  elog(ERROR, "could not find commutator for operator %u",
2267  clause->opno);
2268 
2269  /*
2270  * modify the clause in-place!
2271  */
2272  clause->opno = opoid;
2273  clause->opfuncid = InvalidOid;
2274  /* opresulttype, opretset, opcollid, inputcollid need not change */
2275 
2276  temp = linitial(clause->args);
2277  linitial(clause->args) = lsecond(clause->args);
2278  lsecond(clause->args) = temp;
2279 }
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1313
Definition: nodes.h:509
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#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:497
#define InvalidOid
Definition: postgres_ext.h:36
static int list_length(const List *l)
Definition: pg_list.h:89
Oid opno
Definition: primnodes.h:496
#define elog
Definition: elog.h:219
List * args
Definition: primnodes.h:502
void CommuteRowCompareExpr ( RowCompareExpr clause)

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

2288 {
2289  List *newops;
2290  List *temp;
2291  ListCell *l;
2292 
2293  /* Sanity checks: caller is at fault if these fail */
2294  if (!IsA(clause, RowCompareExpr))
2295  elog(ERROR, "expected a RowCompareExpr");
2296 
2297  /* Build list of commuted operators */
2298  newops = NIL;
2299  foreach(l, clause->opnos)
2300  {
2301  Oid opoid = lfirst_oid(l);
2302 
2303  opoid = get_commutator(opoid);
2304  if (!OidIsValid(opoid))
2305  elog(ERROR, "could not find commutator for operator %u",
2306  lfirst_oid(l));
2307  newops = lappend_oid(newops, opoid);
2308  }
2309 
2310  /*
2311  * modify the clause in-place!
2312  */
2313  switch (clause->rctype)
2314  {
2315  case ROWCOMPARE_LT:
2316  clause->rctype = ROWCOMPARE_GT;
2317  break;
2318  case ROWCOMPARE_LE:
2319  clause->rctype = ROWCOMPARE_GE;
2320  break;
2321  case ROWCOMPARE_GE:
2322  clause->rctype = ROWCOMPARE_LE;
2323  break;
2324  case ROWCOMPARE_GT:
2325  clause->rctype = ROWCOMPARE_LT;
2326  break;
2327  default:
2328  elog(ERROR, "unexpected RowCompare type: %d",
2329  (int) clause->rctype);
2330  break;
2331  }
2332 
2333  clause->opnos = newops;
2334 
2335  /*
2336  * Note: we need not change the opfamilies list; we assume any btree
2337  * opfamily containing an operator will also contain its commutator.
2338  * Collations don't change either.
2339  */
2340 
2341  temp = clause->largs;
2342  clause->largs = clause->rargs;
2343  clause->rargs = temp;
2344 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Oid get_commutator(Oid opno)
Definition: lsyscache.c:1313
RowCompareType rctype
Definition: primnodes.h:1031
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:538
#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
bool contain_agg_clause ( Node clause)

Definition at line 417 of file clauses.c.

References contain_agg_clause_walker(), and NULL.

Referenced by get_eclass_for_sort_expr(), and subquery_planner().

418 {
419  return contain_agg_clause_walker(clause, NULL);
420 }
static bool contain_agg_clause_walker(Node *node, void *context)
Definition: clauses.c:423
#define NULL
Definition: c.h:229
bool contain_leaked_vars ( Node clause)

Definition at line 1481 of file clauses.c.

References contain_leaked_vars_walker(), and NULL.

Referenced by make_restrictinfo_internal(), and qual_is_pushdown_safe().

1482 {
1483  return contain_leaked_vars_walker(clause, NULL);
1484 }
#define NULL
Definition: c.h:229
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition: clauses.c:1493
bool contain_mutable_functions ( Node clause)

Definition at line 878 of file clauses.c.

References contain_mutable_functions_walker(), and NULL.

Referenced by check_index_predicates(), CheckMutability(), ComputePartitionAttrs(), create_bitmap_scan_plan(), create_indexscan_plan(), find_minmax_aggs_walker(), inline_function(), is_foreign_expr(), and relation_excluded_by_constraints().

879 {
880  return contain_mutable_functions_walker(clause, NULL);
881 }
static bool contain_mutable_functions_walker(Node *node, void *context)
Definition: clauses.c:890
#define NULL
Definition: c.h:229
bool contain_nonstrict_functions ( Node clause)

Definition at line 1288 of file clauses.c.

References contain_nonstrict_functions_walker(), and NULL.

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

1289 {
1290  return contain_nonstrict_functions_walker(clause, NULL);
1291 }
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition: clauses.c:1300
#define NULL
Definition: c.h:229
bool contain_subplans ( Node clause)

Definition at line 843 of file clauses.c.

References contain_subplans_walker(), and NULL.

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

844 {
845  return contain_subplans_walker(clause, NULL);
846 }
#define NULL
Definition: c.h:229
static bool contain_subplans_walker(Node *node, void *context)
Definition: clauses.c:849
bool contain_volatile_functions_not_nextval ( Node clause)

Definition at line 1007 of file clauses.c.

References contain_volatile_functions_not_nextval_walker(), and NULL.

Referenced by BeginCopyFrom().

1008 {
1010 }
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition: clauses.c:1020
#define NULL
Definition: c.h:229
bool contain_window_function ( Node clause)

Definition at line 727 of file clauses.c.

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr(), and qual_is_pushdown_safe().

728 {
729  return contain_windowfuncs(clause);
730 }
bool contain_windowfuncs(Node *node)
Definition: rewriteManip.c:197
Node* estimate_expression_value ( PlannerInfo root,
Node node 
)

Definition at line 2454 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, NULL, 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().

2455 {
2457 
2458  context.boundParams = root->glob->boundParams; /* bound Params */
2459  /* we do not need to mark the plan as depending on inlined functions */
2460  context.root = NULL;
2461  context.active_fns = NIL; /* nothing being recursively simplified */
2462  context.case_val = NULL; /* no CASE being examined */
2463  context.estimate = true; /* unsafe transformations OK */
2464  return eval_const_expressions_mutator(node, &context);
2465 }
#define NIL
Definition: pg_list.h:69
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition: clauses.c:2468
ParamListInfo boundParams
Definition: clauses.c:65
PlannerGlobal * glob
Definition: relation.h:157
#define NULL
Definition: c.h:229
ParamListInfo boundParams
Definition: relation.h:96
Node* eval_const_expressions ( PlannerInfo root,
Node node 
)

Definition at line 2421 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, NULL, and eval_const_expressions_context::root.

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

2422 {
2424 
2425  if (root)
2426  context.boundParams = root->glob->boundParams; /* bound Params */
2427  else
2428  context.boundParams = NULL;
2429  context.root = root; /* for inlined-function dependencies */
2430  context.active_fns = NIL; /* nothing being recursively simplified */
2431  context.case_val = NULL; /* no CASE being examined */
2432  context.estimate = false; /* safe transformations only */
2433  return eval_const_expressions_mutator(node, &context);
2434 }
#define NIL
Definition: pg_list.h:69
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition: clauses.c:2468
ParamListInfo boundParams
Definition: clauses.c:65
PlannerGlobal * glob
Definition: relation.h:157
#define NULL
Definition: c.h:229
ParamListInfo boundParams
Definition: relation.h:96
double expression_returns_set_rows ( Node clause)

Definition at line 802 of file clauses.c.

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

Referenced by create_set_projection_path(), and set_function_size_estimates().

803 {
804  if (clause == NULL)
805  return 1.0;
806  if (IsA(clause, FuncExpr))
807  {
808  FuncExpr *expr = (FuncExpr *) clause;
809 
810  if (expr->funcretset)
811  return clamp_row_est(get_func_rows(expr->funcid));
812  }
813  if (IsA(clause, OpExpr))
814  {
815  OpExpr *expr = (OpExpr *) clause;
816 
817  if (expr->opretset)
818  {
819  set_opfuncid(expr);
820  return clamp_row_est(get_func_rows(expr->opfuncid));
821  }
822  }
823  return 1.0;
824 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
float4 get_func_rows(Oid funcid)
Definition: lsyscache.c:1660
bool funcretset
Definition: primnodes.h:451
Oid funcid
Definition: primnodes.h:449
Oid opfuncid
Definition: primnodes.h:497
#define NULL
Definition: c.h:229
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1613
double clamp_row_est(double nrows)
Definition: costsize.c:173
bool opretset
Definition: primnodes.h:499
Var* find_forced_null_var ( Node clause)

Definition at line 2086 of file clauses.c.

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

Referenced by check_redundant_nullability_qual(), and find_forced_null_vars().

2087 {
2088  if (node == NULL)
2089  return NULL;
2090  if (IsA(node, NullTest))
2091  {
2092  /* check for var IS NULL */
2093  NullTest *expr = (NullTest *) node;
2094 
2095  if (expr->nulltesttype == IS_NULL && !expr->argisrow)
2096  {
2097  Var *var = (Var *) expr->arg;
2098 
2099  if (var && IsA(var, Var) &&
2100  var->varlevelsup == 0)
2101  return var;
2102  }
2103  }
2104  else if (IsA(node, BooleanTest))
2105  {
2106  /* var IS UNKNOWN is equivalent to var IS NULL */
2107  BooleanTest *expr = (BooleanTest *) node;
2108 
2109  if (expr->booltesttype == IS_UNKNOWN)
2110  {
2111  Var *var = (Var *) expr->arg;
2112 
2113  if (var && IsA(var, Var) &&
2114  var->varlevelsup == 0)
2115  return var;
2116  }
2117  }
2118  return NULL;
2119 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Index varlevelsup
Definition: primnodes.h:173
Definition: primnodes.h:163
Expr * arg
Definition: primnodes.h:1180
Expr * arg
Definition: primnodes.h:1203
BoolTestType booltesttype
Definition: primnodes.h:1204
NullTestType nulltesttype
Definition: primnodes.h:1181
#define NULL
Definition: c.h:229
bool argisrow
Definition: primnodes.h:1182
List* find_forced_null_vars ( Node clause)

Definition at line 2027 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, NIL, NULL, and result.

Referenced by find_forced_null_vars(), and reduce_outer_joins_pass2().

2028 {
2029  List *result = NIL;
2030  Var *var;
2031  ListCell *l;
2032 
2033  if (node == NULL)
2034  return NIL;
2035  /* Check single-clause cases using subroutine */
2036  var = find_forced_null_var(node);
2037  if (var)
2038  {
2039  result = list_make1(var);
2040  }
2041  /* Otherwise, handle AND-conditions */
2042  else if (IsA(node, List))
2043  {
2044  /*
2045  * At top level, we are examining an implicit-AND list: if any of the
2046  * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
2047  */
2048  foreach(l, (List *) node)
2049  {
2050  result = list_concat(result,
2052  }
2053  }
2054  else if (IsA(node, BoolExpr))
2055  {
2056  BoolExpr *expr = (BoolExpr *) node;
2057 
2058  /*
2059  * We don't bother considering the OR case, because it's fairly
2060  * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
2061  * the NOT case isn't worth expending code on.
2062  */
2063  if (expr->boolop == AND_EXPR)
2064  {
2065  /* At top level we can just recurse (to the List case) */
2066  result = find_forced_null_vars((Node *) expr->args);
2067  }
2068  }
2069  return result;
2070 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
List * list_concat(List *list1, List *list2)
Definition: list.c:321
return result
Definition: formatting.c:1633
Definition: primnodes.h:163
List * find_forced_null_vars(Node *node)
Definition: clauses.c:2027
#define list_make1(x1)
Definition: pg_list.h:139
BoolExprType boolop
Definition: primnodes.h:562
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * args
Definition: primnodes.h:563
Definition: pg_list.h:45
Var * find_forced_null_var(Node *node)
Definition: clauses.c:2086
Relids find_nonnullable_rels ( Node clause)

Definition at line 1626 of file clauses.c.

References find_nonnullable_rels_walker().

Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().

1627 {
1628  return find_nonnullable_rels_walker(clause, true);
1629 }
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition: clauses.c:1632
List* find_nonnullable_vars ( Node clause)

Definition at line 1834 of file clauses.c.

References find_nonnullable_vars_walker().

Referenced by reduce_outer_joins_pass2().

1835 {
1836  return find_nonnullable_vars_walker(clause, true);
1837 }
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition: clauses.c:1840
WindowFuncLists* find_window_functions ( Node clause,
Index  maxWinRef 
)

Definition at line 740 of file clauses.c.

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

Referenced by grouping_planner().

741 {
742  WindowFuncLists *lists = palloc(sizeof(WindowFuncLists));
743 
744  lists->numWindowFuncs = 0;
745  lists->maxWinRef = maxWinRef;
746  lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
747  (void) find_window_functions_walker(clause, lists);
748  return lists;
749 }
Index maxWinRef
Definition: clauses.h:26
int numWindowFuncs
Definition: clauses.h:25
void * palloc0(Size size)
Definition: mcxt.c:878
void * palloc(Size size)
Definition: mcxt.c:849
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition: clauses.c:752
Definition: pg_list.h:45
List ** windowFuncs
Definition: clauses.h:27
void get_agg_clause_costs ( PlannerInfo root,
Node clause,
AggSplit  aggsplit,
AggClauseCosts costs 
)

Definition at line 467 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_grouping_paths(), estimate_path_cost_size(), and grouping_planner().

469 {
471 
472  context.root = root;
473  context.aggsplit = aggsplit;
474  context.costs = costs;
475  (void) get_agg_clause_costs_walker(clause, &context);
476 }
AggClauseCosts * costs
Definition: clauses.c:60
static bool get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context)
Definition: clauses.c:479
Expr* get_notclausearg ( Expr notclause)

Definition at line 265 of file clauses.c.

References generate_unaccent_rules::args, and linitial.

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

266 {
267  return linitial(((BoolExpr *) notclause)->args);
268 }
#define linitial(l)
Definition: pg_list.h:111
Query* inline_set_returning_function ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 4792 of file clauses.c.

References ACL_EXECUTE, ACLCHECK_OK, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), Anum_pg_proc_proconfig, Anum_pg_proc_prosrc, 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::funcresulttype, FuncExpr::funcretset, RangeTblEntry::functions, get_func_result_type(), get_typtype(), GETSTRUCT, GetUserId(), PlannerInfo::glob, heap_attisnull(), HeapTupleIsValid, FuncExpr::inputcollid, PlannerGlobal::invalItems, IsA, linitial, list_concat(), list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, NIL, NULL, 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, PROVOLATILE_VOLATILE, querytree(), record_plan_function_dependency(), RECORDOID, ReleaseSysCache(), RTE_FUNCTION, RangeTblEntry::rtekind, SearchSysCache1, sql_fn_parser_setup(), sql_inline_error_callback(), SQLlanguageId, substitute_actual_srf_parameters(), SysCacheGetAttr(), Query::targetList, TextDatumGetCString, tlist_matches_coltypelist(), TYPEFUNC_RECORD, and TYPTYPE_COMPOSITE.

Referenced by inline_set_returning_functions().

4793 {
4794  RangeTblFunction *rtfunc;
4795  FuncExpr *fexpr;
4796  Oid func_oid;
4797  HeapTuple func_tuple;
4798  Form_pg_proc funcform;
4799  char *src;
4800  Datum tmp;
4801  bool isNull;
4802  bool modifyTargetList;
4803  MemoryContext oldcxt;
4804  MemoryContext mycxt;
4805  List *saveInvalItems;
4806  inline_error_callback_arg callback_arg;
4807  ErrorContextCallback sqlerrcontext;
4809  List *raw_parsetree_list;
4810  List *querytree_list;
4811  Query *querytree;
4812 
4813  Assert(rte->rtekind == RTE_FUNCTION);
4814 
4815  /*
4816  * It doesn't make a lot of sense for a SQL SRF to refer to itself in its
4817  * own FROM clause, since that must cause infinite recursion at runtime.
4818  * It will cause this code to recurse too, so check for stack overflow.
4819  * (There's no need to do more.)
4820  */
4822 
4823  /* Fail if the RTE has ORDINALITY - we don't implement that here. */
4824  if (rte->funcordinality)
4825  return NULL;
4826 
4827  /* Fail if RTE isn't a single, simple FuncExpr */
4828  if (list_length(rte->functions) != 1)
4829  return NULL;
4830  rtfunc = (RangeTblFunction *) linitial(rte->functions);
4831 
4832  if (!IsA(rtfunc->funcexpr, FuncExpr))
4833  return NULL;
4834  fexpr = (FuncExpr *) rtfunc->funcexpr;
4835 
4836  func_oid = fexpr->funcid;
4837 
4838  /*
4839  * The function must be declared to return a set, else inlining would
4840  * change the results if the contained SELECT didn't return exactly one
4841  * row.
4842  */
4843  if (!fexpr->funcretset)
4844  return NULL;
4845 
4846  /*
4847  * Refuse to inline if the arguments contain any volatile functions or
4848  * sub-selects. Volatile functions are rejected because inlining may
4849  * result in the arguments being evaluated multiple times, risking a
4850  * change in behavior. Sub-selects are rejected partly for implementation
4851  * reasons (pushing them down another level might change their behavior)
4852  * and partly because they're likely to be expensive and so multiple
4853  * evaluation would be bad.
4854  */
4855  if (contain_volatile_functions((Node *) fexpr->args) ||
4856  contain_subplans((Node *) fexpr->args))
4857  return NULL;
4858 
4859  /* Check permission to call function (fail later, if not) */
4860  if (pg_proc_aclcheck(func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
4861  return NULL;
4862 
4863  /* Check whether a plugin wants to hook function entry/exit */
4864  if (FmgrHookIsNeeded(func_oid))
4865  return NULL;
4866 
4867  /*
4868  * OK, let's take a look at the function's pg_proc entry.
4869  */
4870  func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid));
4871  if (!HeapTupleIsValid(func_tuple))
4872  elog(ERROR, "cache lookup failed for function %u", func_oid);
4873  funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
4874 
4875  /*
4876  * Forget it if the function is not SQL-language or has other showstopper
4877  * properties. In particular it mustn't be declared STRICT, since we
4878  * couldn't enforce that. It also mustn't be VOLATILE, because that is
4879  * supposed to cause it to be executed with its own snapshot, rather than
4880  * sharing the snapshot of the calling query. (Rechecking proretset is
4881  * just paranoia.)
4882  */
4883  if (funcform->prolang != SQLlanguageId ||
4884  funcform->proisstrict ||
4885  funcform->provolatile == PROVOLATILE_VOLATILE ||
4886  funcform->prosecdef ||
4887  !funcform->proretset ||
4888  !heap_attisnull(func_tuple, Anum_pg_proc_proconfig))
4889  {
4890  ReleaseSysCache(func_tuple);
4891  return NULL;
4892  }
4893 
4894  /*
4895  * Make a temporary memory context, so that we don't leak all the stuff
4896  * that parsing might create.
4897  */
4899  "inline_set_returning_function",
4901  oldcxt = MemoryContextSwitchTo(mycxt);
4902 
4903  /*
4904  * When we call eval_const_expressions below, it might try to add items to
4905  * root->glob->invalItems. Since it is running in the temp context, those
4906  * items will be in that context, and will need to be copied out if we're
4907  * successful. Temporarily reset the list so that we can keep those items
4908  * separate from the pre-existing list contents.
4909  */
4910  saveInvalItems = root->glob->invalItems;
4911  root->glob->invalItems = NIL;
4912 
4913  /* Fetch the function body */
4914  tmp = SysCacheGetAttr(PROCOID,
4915  func_tuple,
4917  &isNull);
4918  if (isNull)
4919  elog(ERROR, "null prosrc for function %u", func_oid);
4920  src = TextDatumGetCString(tmp);
4921 
4922  /*
4923  * Setup error traceback support for ereport(). This is so that we can
4924  * finger the function that bad information came from.
4925  */
4926  callback_arg.proname = NameStr(funcform->proname);
4927  callback_arg.prosrc = src;
4928 
4929  sqlerrcontext.callback = sql_inline_error_callback;
4930  sqlerrcontext.arg = (void *) &callback_arg;
4931  sqlerrcontext.previous = error_context_stack;
4932  error_context_stack = &sqlerrcontext;
4933 
4934  /*
4935  * Run eval_const_expressions on the function call. This is necessary to
4936  * ensure that named-argument notation is converted to positional notation
4937  * and any default arguments are inserted. It's a bit of overkill for the
4938  * arguments, since they'll get processed again later, but no harm will be
4939  * done.
4940  */
4941  fexpr = (FuncExpr *) eval_const_expressions(root, (Node *) fexpr);
4942 
4943  /* It should still be a call of the same function, but let's check */
4944  if (!IsA(fexpr, FuncExpr) ||
4945  fexpr->funcid != func_oid)
4946  goto fail;
4947 
4948  /* Arg list length should now match the function */
4949  if (list_length(fexpr->args) != funcform->pronargs)
4950  goto fail;
4951 
4952  /*
4953  * Set up to handle parameters while parsing the function body. We can
4954  * use the FuncExpr just created as the input for
4955  * prepare_sql_fn_parse_info.
4956  */
4957  pinfo = prepare_sql_fn_parse_info(func_tuple,
4958  (Node *) fexpr,
4959  fexpr->inputcollid);
4960 
4961  /*
4962  * Parse, analyze, and rewrite (unlike inline_function(), we can't skip
4963  * rewriting here). We can fail as soon as we find more than one query,
4964  * though.
4965  */
4966  raw_parsetree_list = pg_parse_query(src);
4967  if (list_length(raw_parsetree_list) != 1)
4968  goto fail;
4969 
4970  querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list),
4971  src,
4973  pinfo, NULL);
4974  if (list_length(querytree_list) != 1)
4975  goto fail;
4976  querytree = linitial(querytree_list);
4977 
4978  /*
4979  * The single command must be a plain SELECT.
4980  */
4981  if (!IsA(querytree, Query) ||
4982  querytree->commandType != CMD_SELECT)
4983  goto fail;
4984 
4985  /*
4986  * Make sure the function (still) returns what it's declared to. This
4987  * will raise an error if wrong, but that's okay since the function would
4988  * fail at runtime anyway. Note that check_sql_fn_retval will also insert
4989  * RelabelType(s) and/or NULL columns if needed to make the tlist
4990  * expression(s) match the declared type of the function.
4991  *
4992  * If the function returns a composite type, don't inline unless the check
4993  * shows it's returning a whole tuple result; otherwise what it's
4994  * returning is a single composite column which is not what we need.
4995  */
4996  if (!check_sql_fn_retval(func_oid, fexpr->funcresulttype,
4997  querytree_list,
4998  &modifyTargetList, NULL) &&
5000  fexpr->funcresulttype == RECORDOID))
5001  goto fail; /* reject not-whole-tuple-result cases */
5002 
5003  /*
5004  * If we had to modify the tlist to make it match, and the statement is
5005  * one in which changing the tlist contents could change semantics, we
5006  * have to punt and not inline.
5007  */
5008  if (modifyTargetList)
5009  goto fail;
5010 
5011  /*
5012  * If it returns RECORD, we have to check against the column type list
5013  * provided in the RTE; check_sql_fn_retval can't do that. (If no match,
5014  * we just fail to inline, rather than complaining; see notes for
5015  * tlist_matches_coltypelist.) We don't have to do this for functions
5016  * with declared OUT parameters, even though their funcresulttype is
5017  * RECORDOID, so check get_func_result_type too.
5018  */
5019  if (fexpr->funcresulttype == RECORDOID &&
5020  get_func_result_type(func_oid, NULL, NULL) == TYPEFUNC_RECORD &&
5022  rtfunc->funccoltypes))
5023  goto fail;
5024 
5025  /*
5026  * Looks good --- substitute parameters into the query.
5027  */
5028  querytree = substitute_actual_srf_parameters(querytree,
5029  funcform->pronargs,
5030  fexpr->args);
5031 
5032  /*
5033  * Copy the modified query out of the temporary memory context, and clean
5034  * up.
5035  */
5036  MemoryContextSwitchTo(oldcxt);
5037 
5038  querytree = copyObject(querytree);
5039 
5040  /* copy up any new invalItems, too */
5041  root->glob->invalItems = list_concat(saveInvalItems,
5042  copyObject(root->glob->invalItems));
5043 
5044  MemoryContextDelete(mycxt);
5045  error_context_stack = sqlerrcontext.previous;
5046  ReleaseSysCache(func_tuple);
5047 
5048  /*
5049  * We don't have to fix collations here because the upper query is already
5050  * parsed, ie, the collations in the RTE are what count.
5051  */
5052 
5053  /*
5054  * Since there is now no trace of the function in the plan tree, we must
5055  * explicitly record the plan's dependency on the function.
5056  */
5057  record_plan_function_dependency(root, func_oid);
5058 
5059  return querytree;
5060 
5061  /* Here if func is not inlinable: release temp memory and return NULL */
5062 fail:
5063  MemoryContextSwitchTo(oldcxt);
5064  root->glob->invalItems = saveInvalItems;
5065  MemoryContextDelete(mycxt);
5066  error_context_stack = sqlerrcontext.previous;
5067  ReleaseSysCache(func_tuple);
5068 
5069  return NULL;
5070 }
Oid funcresulttype
Definition: primnodes.h:450
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
List * args
Definition: primnodes.h:457
Oid GetUserId(void)
Definition: miscinit.c:284
#define TYPTYPE_COMPOSITE
Definition: pg_type.h:721
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
Definition: functions.c:273
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define Anum_pg_proc_prosrc
Definition: pg_proc.h:115
Definition: nodes.h:509
bool check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, bool *modifyTargetList, JunkFilter **junkFilter)
Definition: functions.c:1532
char get_typtype(Oid typid)
Definition: lsyscache.c:2379
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2421
List * list_concat(List *list1, List *list2)
Definition: list.c:321
bool funcretset
Definition: primnodes.h:451
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:957
bool funcordinality
Definition: parsenodes.h:999
unsigned int Oid
Definition: postgres_ext.h:31
struct ErrorContextCallback * previous
Definition: elog.h:238
#define FmgrHookIsNeeded(fn_oid)
Definition: fmgr.h:728
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define Anum_pg_proc_proconfig
Definition: pg_proc.h:117
List * targetList
Definition: parsenodes.h:138
ErrorContextCallback * error_context_stack
Definition: elog.c:88
bool contain_subplans(Node *clause)
Definition: clauses.c:843
#define linitial(l)
Definition: pg_list.h:111
Oid funcid
Definition: primnodes.h:449
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define SQLlanguageId
Definition: pg_language.h:80
List * pg_parse_query(const char *query_string)
Definition: postgres.c:596
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
void check_stack_depth(void)
Definition: postgres.c:3117
PlannerGlobal * glob
Definition: relation.h:157
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
Definition: params.h:66
#define RECORDOID
Definition: pg_type.h:680
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5488
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:269
static void sql_inline_error_callback(void *arg)
Definition: clauses.c:4680
List * invalItems
Definition: relation.h:115
#define TextDatumGetCString(d)
Definition: builtins.h:92
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1279
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition: setrefs.c:2496
static Query * substitute_actual_srf_parameters(Query *expr, int nargs, List *args)
Definition: clauses.c:5079
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
CmdType commandType
Definition: parsenodes.h:110
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
Oid inputcollid
Definition: primnodes.h:456
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
List * functions
Definition: parsenodes.h:998
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:675
Datum querytree(PG_FUNCTION_ARGS)
Definition: _int_bool.c:665
RTEKind rtekind
Definition: parsenodes.h:944
static bool tlist_matches_coltypelist(List *tlist, List *coltypelist)
Definition: clauses.c:5147
void(* callback)(void *arg)
Definition: elog.h:239
#define ACL_EXECUTE
Definition: parsenodes.h:79
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4446
#define NameStr(name)
Definition: c.h:499
#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:622
Definition: pg_list.h:45
bool is_parallel_safe ( PlannerInfo root,
Node node 
)

Definition at line 1087 of file clauses.c.

References PlannerInfo::glob, max_parallel_hazard_context::max_hazard, max_parallel_hazard_context::max_interesting, max_parallel_hazard_walker(), PlannerGlobal::maxParallelHazard, NIL, PlannerGlobal::nParamExec, PROPARALLEL_RESTRICTED, PROPARALLEL_SAFE, and max_parallel_hazard_context::safe_param_ids.

Referenced by apply_projection_to_path(), build_join_rel(), create_grouping_paths(), create_ordered_paths(), create_projection_path(), create_set_projection_path(), create_window_paths(), grouping_planner(), query_planner(), and set_rel_consider_parallel().

1088 {
1090 
1091  /*
1092  * Even if the original querytree contained nothing unsafe, we need to
1093  * search the expression if we have generated any PARAM_EXEC Params while
1094  * planning, because those are parallel-restricted and there might be one
1095  * in this expression. But otherwise we don't need to look.
1096  */
1097  if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
1098  root->glob->nParamExec == 0)
1099  return true;
1100  /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
1101  context.max_hazard = PROPARALLEL_SAFE;
1103  context.safe_param_ids = NIL;
1104  return !max_parallel_hazard_walker(node, &context);
1105 }
char maxParallelHazard
Definition: relation.h:133
#define NIL
Definition: pg_list.h:69
#define PROPARALLEL_RESTRICTED
Definition: pg_proc.h:5496
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:1144
PlannerGlobal * glob
Definition: relation.h:157
#define PROPARALLEL_SAFE
Definition: pg_proc.h:5495
int nParamExec
Definition: relation.h:117
bool is_pseudo_constant_clause ( Node clause)

Definition at line 2196 of file clauses.c.

References contain_var_clause(), and contain_volatile_functions().

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

2197 {
2198  /*
2199  * We could implement this check in one recursive scan. But since the
2200  * check for volatile functions is both moderately expensive and unlikely
2201  * to fail, it seems better to look for Vars first and only check for
2202  * volatile functions if we find no Vars.
2203  */
2204  if (!contain_var_clause(clause) &&
2205  !contain_volatile_functions(clause))
2206  return true;
2207  return false;
2208 }
bool contain_var_clause(Node *node)
Definition: var.c:331
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:957
bool is_pseudo_constant_clause_relids ( Node clause,
Relids  relids 
)

Definition at line 2216 of file clauses.c.

References bms_is_empty(), and contain_volatile_functions().

Referenced by clauselist_selectivity().

2217 {
2218  if (bms_is_empty(relids) &&
2219  !contain_volatile_functions(clause))
2220  return true;
2221  return false;
2222 }
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:957
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:663
Node* make_and_qual ( Node qual1,
Node qual2 
)

Definition at line 348 of file clauses.c.

References list_make2, make_andclause(), and NULL.

Referenced by AddQual(), and subquery_push_qual().

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

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

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

Definition at line 367 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(), show_qual(), and UpdateIndexRelation().

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

Definition at line 378 of file clauses.c.

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

Referenced by ATExecAttachPartition(), convert_EXISTS_to_ANY(), cost_subplan(), DefineIndex(), get_relation_constraints(), preprocess_expression(), RelationGetIndexPredicate(), set_append_rel_size(), and TriggerEnabled().

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

Definition at line 249 of file clauses.c.

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

Referenced by negate_clause().

250 {
251  BoolExpr *expr = makeNode(BoolExpr);
252 
253  expr->boolop = NOT_EXPR;
254  expr->args = list_make1(notclause);
255  expr->location = -1;
256  return (Expr *) expr;
257 }
int location
Definition: primnodes.h:564
#define list_make1(x1)
Definition: pg_list.h:139
BoolExprType boolop
Definition: primnodes.h:562
#define makeNode(_type_)
Definition: nodes.h:557
List * args
Definition: primnodes.h:563
Expr* make_opclause ( Oid  opno,
Oid  opresulttype,
bool  opretset,
Expr leftop,
Expr rightop,
Oid  opcollid,
Oid  inputcollid 
)

Definition at line 172 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(), network_prefix_quals(), operator_predicate_proof(), prefix_quals(), and process_implied_equality().

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

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

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

Definition at line 1068 of file clauses.c.

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

Referenced by standard_planner().

1069 {
1071 
1072  context.max_hazard = PROPARALLEL_SAFE;
1074  context.safe_param_ids = NIL;
1075  (void) max_parallel_hazard_walker((Node *) parse, &context);
1076  return context.max_hazard;
1077 }
#define NIL
Definition: pg_list.h:69
Definition: nodes.h:509
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition: clauses.c:1144
#define PROPARALLEL_SAFE
Definition: pg_proc.h:5495
#define PROPARALLEL_UNSAFE
Definition: pg_proc.h:5497
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
Definition: regcomp.c:649
bool not_clause ( Node clause)

Definition at line 236 of file clauses.c.

References boolop(), IsA, NOT_EXPR, and NULL.

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

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

Definition at line 2238 of file clauses.c.

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

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

2239 {
2240  Relids varnos = pull_varnos(clause);
2241  int result = bms_num_members(varnos);
2242 
2243  bms_free(varnos);
2244  return result;
2245 }
return result
Definition: formatting.c:1633
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:605
Relids pull_varnos(Node *node)
Definition: var.c:95
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201
bool or_clause ( Node clause)

Definition at line 280 of file clauses.c.

References boolop(), IsA, NULL, and OR_EXPR.

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

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