#include "nodes/relation.h"
Go to the source code of this file.
#define is_funcclause | ( | clause | ) | ((clause) != NULL && IsA(clause, FuncExpr)) |
Definition at line 21 of file clauses.h.
Referenced by clause_selectivity(), predicate_implied_by_simple_clause(), and predicate_refuted_by_simple_clause().
#define is_opclause | ( | clause | ) | ((clause) != NULL && IsA(clause, OpExpr)) |
Definition at line 20 of file clauses.h.
Referenced by btree_predicate_proof(), check_hashjoinable(), check_mergejoinable(), clause_selectivity(), clauselist_selectivity(), CommuteOpExpr(), create_hashjoin_plan(), expand_indexqual_conditions(), get_switched_clauses(), make_restrictinfo_internal(), match_clause_to_indexcol(), match_clause_to_ordering_op(), mergejoinscansel(), predicate_implied_by_simple_clause(), predicate_refuted_by_simple_clause(), process_equivalence(), reconsider_full_join_clause(), reconsider_outer_join_clause(), TidListCreate(), and TidQualFromExpr().
Definition at line 299 of file clauses.c.
References AND_EXPR, boolop(), IsA, and NULL.
Referenced by clause_selectivity(), ExecInitSubPlan(), find_duplicate_ors(), generate_bitmap_or_paths(), make_ands_implicit(), make_restrictinfo(), make_sub_restrictinfos(), predicate_classify(), process_duplicate_ors(), process_sublinks_mutator(), pull_ands(), pull_up_sublinks_qual_recurse(), simplify_and_arguments(), testexpr_is_hashable(), and TidQualFromExpr().
void CommuteOpExpr | ( | OpExpr * | clause | ) |
Definition at line 1969 of file clauses.c.
References OpExpr::args, elog, ERROR, get_commutator(), is_opclause, linitial, list_length(), lsecond, OidIsValid, OpExpr::opfuncid, and OpExpr::opno.
Referenced by fix_indexqual_references(), and get_switched_clauses().
{ Oid opoid; Node *temp; /* Sanity checks: caller is at fault if these fail */ if (!is_opclause(clause) || list_length(clause->args) != 2) elog(ERROR, "cannot commute non-binary-operator clause"); opoid = get_commutator(clause->opno); if (!OidIsValid(opoid)) elog(ERROR, "could not find commutator for operator %u", clause->opno); /* * modify the clause in-place! */ clause->opno = opoid; clause->opfuncid = InvalidOid; /* opresulttype, opretset, opcollid, inputcollid need not change */ temp = linitial(clause->args); linitial(clause->args) = lsecond(clause->args); lsecond(clause->args) = temp; }
void CommuteRowCompareExpr | ( | RowCompareExpr * | clause | ) |
Definition at line 2003 of file clauses.c.
References elog, ERROR, get_commutator(), IsA, lappend_oid(), RowCompareExpr::largs, lfirst_oid, OidIsValid, RowCompareExpr::opnos, RowCompareExpr::rargs, RowCompareExpr::rctype, ROWCOMPARE_GE, ROWCOMPARE_GT, ROWCOMPARE_LE, and ROWCOMPARE_LT.
Referenced by fix_indexqual_references().
{ List *newops; List *temp; ListCell *l; /* Sanity checks: caller is at fault if these fail */ if (!IsA(clause, RowCompareExpr)) elog(ERROR, "expected a RowCompareExpr"); /* Build list of commuted operators */ newops = NIL; foreach(l, clause->opnos) { Oid opoid = lfirst_oid(l); opoid = get_commutator(opoid); if (!OidIsValid(opoid)) elog(ERROR, "could not find commutator for operator %u", lfirst_oid(l)); newops = lappend_oid(newops, opoid); } /* * modify the clause in-place! */ switch (clause->rctype) { case ROWCOMPARE_LT: clause->rctype = ROWCOMPARE_GT; break; case ROWCOMPARE_LE: clause->rctype = ROWCOMPARE_GE; break; case ROWCOMPARE_GE: clause->rctype = ROWCOMPARE_LE; break; case ROWCOMPARE_GT: clause->rctype = ROWCOMPARE_LT; break; default: elog(ERROR, "unexpected RowCompare type: %d", (int) clause->rctype); break; } clause->opnos = newops; /* * Note: we need not change the opfamilies list; we assume any btree * opfamily containing an operator will also contain its commutator. * Collations don't change either. */ temp = clause->largs; clause->largs = clause->rargs; clause->rargs = temp; }
Definition at line 402 of file clauses.c.
References contain_agg_clause_walker(), and NULL.
Referenced by count_agg_clauses_walker(), get_eclass_for_sort_expr(), and subquery_planner().
{ return contain_agg_clause_walker(clause, NULL); }
Definition at line 1182 of file clauses.c.
References contain_leaky_functions_walker(), and NULL.
Referenced by set_subquery_pathlist().
{ return contain_leaky_functions_walker(clause, NULL); }
Definition at line 829 of file clauses.c.
References contain_mutable_functions_walker(), and NULL.
Referenced by CheckMutability(), create_bitmap_scan_plan(), create_indexscan_plan(), find_minmax_aggs_walker(), inline_function(), is_foreign_expr(), and relation_excluded_by_constraints().
{ return contain_mutable_functions_walker(clause, NULL); }
Definition at line 1061 of file clauses.c.
References contain_nonstrict_functions_walker(), and NULL.
Referenced by inline_function(), process_equivalence(), and pullup_replace_vars_callback().
{ return contain_nonstrict_functions_walker(clause, NULL); }
Definition at line 794 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().
{ return contain_subplans_walker(clause, NULL); }
Definition at line 944 of file clauses.c.
References contain_volatile_functions_walker(), and NULL.
Referenced by adjust_rowcompare_for_index(), BeginCopyFrom(), check_hashjoinable(), check_mergejoinable(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), convert_EXISTS_to_ANY(), create_unique_path(), distribute_qual_to_rels(), estimate_num_groups(), ExecInitAgg(), ExecInitWindowAgg(), get_eclass_for_sort_expr(), inline_function(), inline_set_returning_function(), is_pseudo_constant_clause(), is_pseudo_constant_clause_relids(), is_simple_subquery(), make_restrictinfos_from_actual_clauses(), match_clause_to_indexcol(), match_clause_to_ordering_op(), match_rowcompare_to_indexcol(), qual_is_pushdown_safe(), and subquery_planner().
{ return contain_volatile_functions_walker(clause, NULL); }
Definition at line 599 of file clauses.c.
References contain_windowfuncs().
Referenced by find_window_functions_walker(), get_eclass_for_sort_expr(), and qual_is_pushdown_safe().
{ return contain_windowfuncs(clause); }
void count_agg_clauses | ( | PlannerInfo * | root, | |
Node * | clause, | |||
AggClauseCosts * | costs | |||
) |
Definition at line 441 of file clauses.c.
References count_agg_clauses_context::costs, count_agg_clauses_walker(), and count_agg_clauses_context::root.
Referenced by grouping_planner().
{ count_agg_clauses_context context; context.root = root; context.costs = costs; (void) count_agg_clauses_walker(clause, &context); }
Node* estimate_expression_value | ( | PlannerInfo * | root, | |
Node * | node | |||
) |
Definition at line 2226 of file clauses.c.
References eval_const_expressions_context::active_fns, PlannerGlobal::boundParams, eval_const_expressions_context::boundParams, eval_const_expressions_context::case_val, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), PlannerInfo::glob, and eval_const_expressions_context::root.
Referenced by clause_selectivity(), get_restriction_variable(), preprocess_limit(), and scalararraysel_containment().
{ eval_const_expressions_context context; context.boundParams = root->glob->boundParams; /* bound Params */ /* we do not need to mark the plan as depending on inlined functions */ context.root = NULL; context.active_fns = NIL; /* nothing being recursively simplified */ context.case_val = NULL; /* no CASE being examined */ context.estimate = true; /* unsafe transformations OK */ return eval_const_expressions_mutator(node, &context); }
Node* eval_const_expressions | ( | PlannerInfo * | root, | |
Node * | node | |||
) |
Definition at line 2193 of file clauses.c.
References eval_const_expressions_context::active_fns, PlannerGlobal::boundParams, eval_const_expressions_context::boundParams, eval_const_expressions_context::case_val, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), PlannerInfo::glob, and eval_const_expressions_context::root.
Referenced by convert_EXISTS_to_ANY(), expression_planner(), get_relation_constraints(), inline_set_returning_function(), preprocess_expression(), process_implied_equality(), RelationGetIndexExpressions(), RelationGetIndexPredicate(), and set_append_rel_size().
{ eval_const_expressions_context context; if (root) context.boundParams = root->glob->boundParams; /* bound Params */ else context.boundParams = NULL; context.root = root; /* for inlined-function dependencies */ context.active_fns = NIL; /* nothing being recursively simplified */ context.case_val = NULL; /* no CASE being examined */ context.estimate = false; /* safe transformations only */ return eval_const_expressions_mutator(node, &context); }
double expression_returns_set_rows | ( | Node * | clause | ) |
Definition at line 676 of file clauses.c.
References clamp_row_est(), and expression_returns_set_rows_walker().
Referenced by set_function_size_estimates(), and tlist_returns_set_rows().
{ double result = 1; (void) expression_returns_set_rows_walker(clause, &result); return clamp_row_est(result); }
Definition at line 1802 of file clauses.c.
References BooleanTest::arg, NullTest::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().
{ if (node == NULL) return NULL; if (IsA(node, NullTest)) { /* check for var IS NULL */ NullTest *expr = (NullTest *) node; if (expr->nulltesttype == IS_NULL && !expr->argisrow) { Var *var = (Var *) expr->arg; if (var && IsA(var, Var) && var->varlevelsup == 0) return var; } } else if (IsA(node, BooleanTest)) { /* var IS UNKNOWN is equivalent to var IS NULL */ BooleanTest *expr = (BooleanTest *) node; if (expr->booltesttype == IS_UNKNOWN) { Var *var = (Var *) expr->arg; if (var && IsA(var, Var) && var->varlevelsup == 0) return var; } } return NULL; }
Definition at line 1743 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 NULL.
Referenced by find_forced_null_vars(), and reduce_outer_joins_pass2().
{ List *result = NIL; Var *var; ListCell *l; if (node == NULL) return NIL; /* Check single-clause cases using subroutine */ var = find_forced_null_var(node); if (var) { result = list_make1(var); } /* Otherwise, handle AND-conditions */ else if (IsA(node, List)) { /* * At top level, we are examining an implicit-AND list: if any of the * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. */ foreach(l, (List *) node) { result = list_concat(result, find_forced_null_vars(lfirst(l))); } } else if (IsA(node, BoolExpr)) { BoolExpr *expr = (BoolExpr *) node; /* * We don't bother considering the OR case, because it's fairly * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise, * the NOT case isn't worth expending code on. */ if (expr->boolop == AND_EXPR) { /* At top level we can just recurse (to the List case) */ result = find_forced_null_vars((Node *) expr->args); } } return result; }
Definition at line 1342 of file clauses.c.
References find_nonnullable_rels_walker().
Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().
{ return find_nonnullable_rels_walker(clause, true); }
Definition at line 1550 of file clauses.c.
References find_nonnullable_vars_walker().
Referenced by reduce_outer_joins_pass2().
{ return find_nonnullable_vars_walker(clause, true); }
WindowFuncLists* find_window_functions | ( | Node * | clause, | |
Index | maxWinRef | |||
) |
Definition at line 612 of file clauses.c.
References find_window_functions_walker(), WindowFuncLists::maxWinRef, WindowFuncLists::numWindowFuncs, palloc(), palloc0(), and WindowFuncLists::windowFuncs.
Referenced by grouping_planner().
{ WindowFuncLists *lists = palloc(sizeof(WindowFuncLists)); lists->numWindowFuncs = 0; lists->maxWinRef = maxWinRef; lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *)); (void) find_window_functions_walker(clause, lists); return lists; }
Definition at line 184 of file clauses.c.
References OpExpr::args, linitial, and NIL.
Referenced by addRangeClause(), btcostestimate(), btree_predicate_proof(), ExecIndexBuildScanKeys(), expand_indexqual_opclause(), final_cost_hashjoin(), gincost_opexpr(), initialize_mergeclause_eclasses(), make_restrictinfo_internal(), match_clause_to_indexcol(), match_clause_to_ordering_op(), mergejoinscansel(), print_expr(), process_equivalence(), reconsider_full_join_clause(), reconsider_outer_join_clause(), relation_has_unique_index_for(), and TidListCreate().
Definition at line 250 of file clauses.c.
References linitial.
Referenced by clause_selectivity(), expand_boolean_index_clause(), match_boolean_index_clause(), and pull_up_sublinks_qual_recurse().
Definition at line 201 of file clauses.c.
References OpExpr::args, list_length(), and lsecond.
Referenced by addRangeClause(), btcostestimate(), btree_predicate_proof(), ExecIndexBuildScanKeys(), expand_indexqual_opclause(), final_cost_hashjoin(), gincost_opexpr(), initialize_mergeclause_eclasses(), make_restrictinfo_internal(), match_clause_to_indexcol(), match_clause_to_ordering_op(), match_special_index_operator(), mergejoinscansel(), print_expr(), process_equivalence(), reconsider_full_join_clause(), reconsider_outer_join_clause(), relation_has_unique_index_for(), and TidListCreate().
Query* inline_set_returning_function | ( | PlannerInfo * | root, | |
RangeTblEntry * | rte | |||
) |
Definition at line 4470 of file clauses.c.
References ACL_EXECUTE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, 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, RangeTblEntry::funccoltypes, RangeTblEntry::funcexpr, FuncExpr::funcid, FuncExpr::funcretset, get_func_result_type(), get_typtype(), GETSTRUCT, GetUserId(), PlannerInfo::glob, heap_attisnull(), HeapTupleIsValid, PlannerGlobal::invalItems, IsA, linitial, list_concat(), list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, 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, record_plan_function_dependency(), RECORDOID, ReleaseSysCache(), RTE_FUNCTION, RangeTblEntry::rtekind, SearchSysCache1, sql_fn_parser_setup(), SQLlanguageId, substitute_actual_srf_parameters(), SysCacheGetAttr(), Query::targetList, TextDatumGetCString, tlist_matches_coltypelist(), TYPEFUNC_RECORD, TYPTYPE_COMPOSITE, and Query::utilityStmt.
Referenced by inline_set_returning_functions().
{ FuncExpr *fexpr; Oid func_oid; HeapTuple func_tuple; Form_pg_proc funcform; char *src; Datum tmp; bool isNull; bool modifyTargetList; MemoryContext oldcxt; MemoryContext mycxt; List *saveInvalItems; inline_error_callback_arg callback_arg; ErrorContextCallback sqlerrcontext; SQLFunctionParseInfoPtr pinfo; List *raw_parsetree_list; List *querytree_list; Query *querytree; Assert(rte->rtekind == RTE_FUNCTION); /* * It doesn't make a lot of sense for a SQL SRF to refer to itself in its * own FROM clause, since that must cause infinite recursion at runtime. * It will cause this code to recurse too, so check for stack overflow. * (There's no need to do more.) */ check_stack_depth(); /* Fail if FROM item isn't a simple FuncExpr */ fexpr = (FuncExpr *) rte->funcexpr; if (fexpr == NULL || !IsA(fexpr, FuncExpr)) return NULL; func_oid = fexpr->funcid; /* * The function must be declared to return a set, else inlining would * change the results if the contained SELECT didn't return exactly one * row. */ if (!fexpr->funcretset) return NULL; /* * Refuse to inline if the arguments contain any volatile functions or * sub-selects. Volatile functions are rejected because inlining may * result in the arguments being evaluated multiple times, risking a * change in behavior. Sub-selects are rejected partly for implementation * reasons (pushing them down another level might change their behavior) * and partly because they're likely to be expensive and so multiple * evaluation would be bad. */ if (contain_volatile_functions((Node *) fexpr->args) || contain_subplans((Node *) fexpr->args)) return NULL; /* Check permission to call function (fail later, if not) */ if (pg_proc_aclcheck(func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK) return NULL; /* Check whether a plugin wants to hook function entry/exit */ if (FmgrHookIsNeeded(func_oid)) return NULL; /* * OK, let's take a look at the function's pg_proc entry. */ func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid)); if (!HeapTupleIsValid(func_tuple)) elog(ERROR, "cache lookup failed for function %u", func_oid); funcform = (Form_pg_proc) GETSTRUCT(func_tuple); /* * Forget it if the function is not SQL-language or has other showstopper * properties. In particular it mustn't be declared STRICT, since we * couldn't enforce that. It also mustn't be VOLATILE, because that is * supposed to cause it to be executed with its own snapshot, rather than * sharing the snapshot of the calling query. (Rechecking proretset is * just paranoia.) */ if (funcform->prolang != SQLlanguageId || funcform->proisstrict || funcform->provolatile == PROVOLATILE_VOLATILE || funcform->prosecdef || !funcform->proretset || !heap_attisnull(func_tuple, Anum_pg_proc_proconfig)) { ReleaseSysCache(func_tuple); return NULL; } /* * Make a temporary memory context, so that we don't leak all the stuff * that parsing might create. */ mycxt = AllocSetContextCreate(CurrentMemoryContext, "inline_set_returning_function", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldcxt = MemoryContextSwitchTo(mycxt); /* * When we call eval_const_expressions below, it might try to add items to * root->glob->invalItems. Since it is running in the temp context, those * items will be in that context, and will need to be copied out if we're * successful. Temporarily reset the list so that we can keep those items * separate from the pre-existing list contents. */ saveInvalItems = root->glob->invalItems; root->glob->invalItems = NIL; /* Fetch the function body */ tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosrc, &isNull); if (isNull) elog(ERROR, "null prosrc for function %u", func_oid); src = TextDatumGetCString(tmp); /* * Setup error traceback support for ereport(). This is so that we can * finger the function that bad information came from. */ callback_arg.proname = NameStr(funcform->proname); callback_arg.prosrc = src; sqlerrcontext.callback = sql_inline_error_callback; sqlerrcontext.arg = (void *) &callback_arg; sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; /* * Run eval_const_expressions on the function call. This is necessary to * ensure that named-argument notation is converted to positional notation * and any default arguments are inserted. It's a bit of overkill for the * arguments, since they'll get processed again later, but no harm will be * done. */ fexpr = (FuncExpr *) eval_const_expressions(root, (Node *) fexpr); /* It should still be a call of the same function, but let's check */ if (!IsA(fexpr, FuncExpr) || fexpr->funcid != func_oid) goto fail; /* Arg list length should now match the function */ if (list_length(fexpr->args) != funcform->pronargs) goto fail; /* * Set up to handle parameters while parsing the function body. We can * use the FuncExpr just created as the input for * prepare_sql_fn_parse_info. */ pinfo = prepare_sql_fn_parse_info(func_tuple, (Node *) fexpr, fexpr->inputcollid); /* * Parse, analyze, and rewrite (unlike inline_function(), we can't skip * rewriting here). We can fail as soon as we find more than one query, * though. */ raw_parsetree_list = pg_parse_query(src); if (list_length(raw_parsetree_list) != 1) goto fail; querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list), src, (ParserSetupHook) sql_fn_parser_setup, pinfo); if (list_length(querytree_list) != 1) goto fail; querytree = linitial(querytree_list); /* * The single command must be a plain SELECT. */ if (!IsA(querytree, Query) || querytree->commandType != CMD_SELECT || querytree->utilityStmt) goto fail; /* * Make sure the function (still) returns what it's declared to. This * will raise an error if wrong, but that's okay since the function would * fail at runtime anyway. Note that check_sql_fn_retval will also insert * RelabelType(s) and/or NULL columns if needed to make the tlist * expression(s) match the declared type of the function. * * If the function returns a composite type, don't inline unless the check * shows it's returning a whole tuple result; otherwise what it's * returning is a single composite column which is not what we need. */ if (!check_sql_fn_retval(func_oid, fexpr->funcresulttype, querytree_list, &modifyTargetList, NULL) && (get_typtype(fexpr->funcresulttype) == TYPTYPE_COMPOSITE || fexpr->funcresulttype == RECORDOID)) goto fail; /* reject not-whole-tuple-result cases */ /* * If we had to modify the tlist to make it match, and the statement is * one in which changing the tlist contents could change semantics, we * have to punt and not inline. */ if (modifyTargetList) goto fail; /* * If it returns RECORD, we have to check against the column type list * provided in the RTE; check_sql_fn_retval can't do that. (If no match, * we just fail to inline, rather than complaining; see notes for * tlist_matches_coltypelist.) We don't have to do this for functions * with declared OUT parameters, even though their funcresulttype is * RECORDOID, so check get_func_result_type too. */ if (fexpr->funcresulttype == RECORDOID && get_func_result_type(func_oid, NULL, NULL) == TYPEFUNC_RECORD && !tlist_matches_coltypelist(querytree->targetList, rte->funccoltypes)) goto fail; /* * Looks good --- substitute parameters into the query. */ querytree = substitute_actual_srf_parameters(querytree, funcform->pronargs, fexpr->args); /* * Copy the modified query out of the temporary memory context, and clean * up. */ MemoryContextSwitchTo(oldcxt); querytree = copyObject(querytree); /* copy up any new invalItems, too */ root->glob->invalItems = list_concat(saveInvalItems, copyObject(root->glob->invalItems)); MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); /* * We don't have to fix collations here because the upper query is already * parsed, ie, the collations in the RTE are what count. */ /* * Since there is now no trace of the function in the plan tree, we must * explicitly record the plan's dependency on the function. */ record_plan_function_dependency(root, func_oid); return querytree; /* Here if func is not inlinable: release temp memory and return NULL */ fail: MemoryContextSwitchTo(oldcxt); root->glob->invalItems = saveInvalItems; MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); return NULL; }
Definition at line 1912 of file clauses.c.
References contain_var_clause(), and contain_volatile_functions().
Referenced by clauselist_selectivity(), IsTidEqualAnyClause(), and IsTidEqualClause().
{ /* * We could implement this check in one recursive scan. But since the * check for volatile functions is both moderately expensive and unlikely * to fail, it seems better to look for Vars first and only check for * volatile functions if we find no Vars. */ if (!contain_var_clause(clause) && !contain_volatile_functions(clause)) return true; return false; }
Definition at line 1932 of file clauses.c.
References bms_is_empty(), and contain_volatile_functions().
Referenced by clauselist_selectivity().
{ if (bms_is_empty(relids) && !contain_volatile_functions(clause)) return true; return false; }
Definition at line 333 of file clauses.c.
References list_make2, make_andclause(), and NULL.
Referenced by AddQual(), and subquery_push_qual().
{ if (qual1 == NULL) return qual2; if (qual2 == NULL) return qual1; return (Node *) make_andclause(list_make2(qual1, qual2)); }
Definition at line 312 of file clauses.c.
References BoolExpr::args, BoolExpr::boolop, BoolExpr::location, and makeNode.
Referenced by eval_const_expressions_mutator(), find_duplicate_ors(), make_and_qual(), make_ands_explicit(), make_restrictinfo_from_bitmapqual(), make_sub_restrictinfos(), negate_clause(), process_duplicate_ors(), process_sublinks_mutator(), and pull_up_sublinks_qual_recurse().
Definition at line 352 of file clauses.c.
References linitial, list_length(), make_andclause(), makeBoolConst(), and NIL.
Referenced by convert_EXISTS_to_ANY(), create_bitmap_subplan(), set_append_rel_size(), show_qual(), and UpdateIndexRelation().
{ if (andclauses == NIL) return (Expr *) makeBoolConst(true, false); else if (list_length(andclauses) == 1) return (Expr *) linitial(andclauses); else return make_andclause(andclauses); }
Definition at line 363 of file clauses.c.
References and_clause(), DatumGetBool, IsA, list_make1, and NULL.
Referenced by ATAddCheckConstraint(), convert_EXISTS_to_ANY(), cost_subplan(), DefineIndex(), ExecRelCheck(), get_relation_constraints(), preprocess_expression(), RelationGetIndexPredicate(), set_append_rel_size(), TriggerEnabled(), and validateCheckConstraint().
{ /* * NB: because the parser sets the qual field to NULL in a query that has * no WHERE clause, we must consider a NULL input clause as TRUE, even * though one might more reasonably think it FALSE. Grumble. If this * causes trouble, consider changing the parser's behavior. */ if (clause == NULL) return NIL; /* NULL -> NIL list == TRUE */ else if (and_clause((Node *) clause)) return ((BoolExpr *) clause)->args; else if (IsA(clause, Const) && !((Const *) clause)->constisnull && DatumGetBool(((Const *) clause)->constvalue)) return NIL; /* constant TRUE input -> NIL list */ else return list_make1(clause); }
Definition at line 234 of file clauses.c.
References BoolExpr::args, BoolExpr::boolop, list_make1, BoolExpr::location, and makeNode.
Referenced by negate_clause().
Expr* make_opclause | ( | Oid | opno, | |
Oid | opresulttype, | |||
bool | opretset, | |||
Expr * | leftop, | |||
Expr * | rightop, | |||
Oid | opcollid, | |||
Oid | inputcollid | |||
) |
Definition at line 157 of file clauses.c.
References OpExpr::args, OpExpr::inputcollid, list_make1, list_make2, OpExpr::location, makeNode, OpExpr::opcollid, OpExpr::opfuncid, OpExpr::opno, OpExpr::opresulttype, and OpExpr::opretset.
Referenced by adjust_rowcompare_for_index(), btree_predicate_proof(), build_implied_join_equality(), convert_EXISTS_to_ANY(), expand_boolean_index_clause(), network_prefix_quals(), prefix_quals(), and process_implied_equality().
{ OpExpr *expr = makeNode(OpExpr); expr->opno = opno; expr->opfuncid = InvalidOid; expr->opresulttype = opresulttype; expr->opretset = opretset; expr->opcollid = opcollid; expr->inputcollid = inputcollid; if (rightop) expr->args = list_make2(leftop, rightop); else expr->args = list_make1(leftop); expr->location = -1; return (Expr *) expr; }
Definition at line 278 of file clauses.c.
References BoolExpr::args, BoolExpr::boolop, BoolExpr::location, and makeNode.
Referenced by create_bitmap_subplan(), create_tidscan_plan(), eval_const_expressions_mutator(), ExplainNode(), make_restrictinfo_from_bitmapqual(), make_sub_restrictinfos(), negate_clause(), process_duplicate_ors(), and process_sublinks_mutator().
Definition at line 221 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().
int NumRelids | ( | Node * | clause | ) |
Definition at line 1954 of file clauses.c.
References bms_free(), bms_num_members(), and pull_varnos().
Referenced by clauselist_selectivity(), rowcomparesel(), and treat_as_join_clause().
{ Relids varnos = pull_varnos(clause); int result = bms_num_members(varnos); bms_free(varnos); return result; }
Definition at line 265 of file clauses.c.
References boolop(), IsA, NULL, and OR_EXPR.
Referenced by clause_selectivity(), find_duplicate_ors(), make_restrictinfo(), make_restrictinfo_from_bitmapqual(), make_sub_restrictinfos(), predicate_classify(), process_sublinks_mutator(), pull_ors(), simplify_or_arguments(), and TidQualFromExpr().
Definition at line 2069 of file clauses.c.
References CoerceToDomain::arg, ConvertRowtypeExpr::arg, ArrayCoerceExpr::arg, CoerceViaIO::arg, RelabelType::arg, FuncExpr::args, COERCE_IMPLICIT_CAST, ArrayCoerceExpr::coerceformat, CoerceViaIO::coerceformat, CoerceToDomain::coercionformat, ConvertRowtypeExpr::convertformat, FuncExpr::funcformat, IsA, linitial, NULL, RelabelType::relabelformat, and strip_implicit_coercions().
Referenced by ATExecAlterColumnType(), findTargetlistEntrySQL99(), flatten_join_using_qual(), get_rule_expr(), and strip_implicit_coercions().
{ if (node == NULL) return NULL; if (IsA(node, FuncExpr)) { FuncExpr *f = (FuncExpr *) node; if (f->funcformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions(linitial(f->args)); } else if (IsA(node, RelabelType)) { RelabelType *r = (RelabelType *) node; if (r->relabelformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions((Node *) r->arg); } else if (IsA(node, CoerceViaIO)) { CoerceViaIO *c = (CoerceViaIO *) node; if (c->coerceformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions((Node *) c->arg); } else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *c = (ArrayCoerceExpr *) node; if (c->coerceformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions((Node *) c->arg); } else if (IsA(node, ConvertRowtypeExpr)) { ConvertRowtypeExpr *c = (ConvertRowtypeExpr *) node; if (c->convertformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions((Node *) c->arg); } else if (IsA(node, CoerceToDomain)) { CoerceToDomain *c = (CoerceToDomain *) node; if (c->coercionformat == COERCE_IMPLICIT_CAST) return strip_implicit_coercions((Node *) c->arg); } return node; }
double tlist_returns_set_rows | ( | List * | tlist | ) |
Definition at line 760 of file clauses.c.
References TargetEntry::expr, expression_returns_set_rows(), and lfirst.
Referenced by add_tlist_costs_to_plan().
{ double result = 1; ListCell *lc; foreach(lc, tlist) { TargetEntry *tle = (TargetEntry *) lfirst(lc); double colresult; colresult = expression_returns_set_rows((Node *) tle->expr); if (result < colresult) result = colresult; } return result; }