PostgreSQL Source Code git master
optimizer.h File Reference
#include "nodes/parsenodes.h"
Include dependency graph for optimizer.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PVC_INCLUDE_AGGREGATES   0x0001 /* include Aggrefs in output list */
 
#define PVC_RECURSE_AGGREGATES   0x0002 /* recurse into Aggref arguments */
 
#define PVC_INCLUDE_WINDOWFUNCS   0x0004 /* include WindowFuncs in output list */
 
#define PVC_RECURSE_WINDOWFUNCS   0x0008 /* recurse into WindowFunc arguments */
 
#define PVC_INCLUDE_PLACEHOLDERS
 
#define PVC_RECURSE_PLACEHOLDERS
 
#define PVC_INCLUDE_CONVERTROWTYPES
 

Typedefs

typedef struct ExplainState ExplainState
 
typedef struct PlannerInfo PlannerInfo
 
typedef struct IndexOptInfo IndexOptInfo
 
typedef struct SpecialJoinInfo SpecialJoinInfo
 
typedef struct PlannedStmt PlannedStmt
 
typedef struct ParamListInfoDataParamListInfo
 
typedef struct HeapTupleDataHeapTuple
 

Enumerations

enum  DebugParallelMode { DEBUG_PARALLEL_OFF , DEBUG_PARALLEL_ON , DEBUG_PARALLEL_REGRESS }
 

Functions

Selectivity clause_selectivity (PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
 
Selectivity clause_selectivity_ext (PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
 
Selectivity clauselist_selectivity (PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
 
Selectivity clauselist_selectivity_ext (PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
 
double clamp_row_est (double nrows)
 
int32 clamp_width_est (int64 tuple_width)
 
bool is_pseudo_constant_for_index (PlannerInfo *root, Node *expr, IndexOptInfo *index)
 
PlannedStmtplanner (Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
 
Exprexpression_planner (Expr *expr)
 
Exprexpression_planner_with_deps (Expr *expr, List **relationOids, List **invalItems)
 
bool plan_cluster_use_sort (Oid tableOid, Oid indexOid)
 
int plan_create_index_workers (Oid tableOid, Oid indexOid)
 
void extract_query_dependencies (Node *query, List **relationOids, List **invalItems, bool *hasRowSecurity)
 
Nodenegate_clause (Node *node)
 
Exprcanonicalize_qual (Expr *qual, bool is_check)
 
bool contain_mutable_functions (Node *clause)
 
bool contain_mutable_functions_after_planning (Expr *expr)
 
bool contain_volatile_functions (Node *clause)
 
bool contain_volatile_functions_after_planning (Expr *expr)
 
bool contain_volatile_functions_not_nextval (Node *clause)
 
Nodeeval_const_expressions (PlannerInfo *root, Node *node)
 
void convert_saop_to_hashed_saop (Node *node)
 
Nodeestimate_expression_value (PlannerInfo *root, Node *node)
 
Exprevaluate_expr (Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation)
 
bool var_is_nonnullable (PlannerInfo *root, Var *var, bool use_rel_info)
 
bool expr_is_nonnullable (PlannerInfo *root, Expr *expr, bool use_rel_info)
 
Listexpand_function_arguments (List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
 
ScalarArrayOpExprmake_SAOP_expr (Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, Oid inputcollid, List *exprs, bool haveNonConst)
 
bool predicate_implied_by (List *predicate_list, List *clause_list, bool weak)
 
bool predicate_refuted_by (List *predicate_list, List *clause_list, bool weak)
 
int count_nonjunk_tlist_entries (List *tlist)
 
TargetEntryget_sortgroupref_tle (Index sortref, List *targetList)
 
TargetEntryget_sortgroupclause_tle (SortGroupClause *sgClause, List *targetList)
 
Nodeget_sortgroupclause_expr (SortGroupClause *sgClause, List *targetList)
 
Listget_sortgrouplist_exprs (List *sgClauses, List *targetList)
 
SortGroupClauseget_sortgroupref_clause (Index sortref, List *clauses)
 
SortGroupClauseget_sortgroupref_clause_noerr (Index sortref, List *clauses)
 
Bitmapsetpull_varnos (PlannerInfo *root, Node *node)
 
Bitmapsetpull_varnos_of_level (PlannerInfo *root, Node *node, int levelsup)
 
void pull_varattnos (Node *node, Index varno, Bitmapset **varattnos)
 
Listpull_vars_of_level (Node *node, int levelsup)
 
bool contain_var_clause (Node *node)
 
bool contain_vars_of_level (Node *node, int levelsup)
 
bool contain_vars_returning_old_or_new (Node *node)
 
int locate_var_of_level (Node *node, int levelsup)
 
Listpull_var_clause (Node *node, int flags)
 
Nodeflatten_join_alias_vars (PlannerInfo *root, Query *query, Node *node)
 
Nodeflatten_group_exprs (PlannerInfo *root, Query *query, Node *node)
 

Variables

PGDLLIMPORT double seq_page_cost
 
PGDLLIMPORT double random_page_cost
 
PGDLLIMPORT double cpu_tuple_cost
 
PGDLLIMPORT double cpu_index_tuple_cost
 
PGDLLIMPORT double cpu_operator_cost
 
PGDLLIMPORT double parallel_tuple_cost
 
PGDLLIMPORT double parallel_setup_cost
 
PGDLLIMPORT double recursive_worktable_factor
 
PGDLLIMPORT int effective_cache_size
 
PGDLLIMPORT int debug_parallel_query
 
PGDLLIMPORT bool parallel_leader_participation
 
PGDLLIMPORT bool enable_distinct_reordering
 

Macro Definition Documentation

◆ PVC_INCLUDE_AGGREGATES

#define PVC_INCLUDE_AGGREGATES   0x0001 /* include Aggrefs in output list */

Definition at line 188 of file optimizer.h.

◆ PVC_INCLUDE_CONVERTROWTYPES

#define PVC_INCLUDE_CONVERTROWTYPES
Value:
0x0040 /* include ConvertRowtypeExprs in
* output list */

Definition at line 194 of file optimizer.h.

◆ PVC_INCLUDE_PLACEHOLDERS

#define PVC_INCLUDE_PLACEHOLDERS
Value:
0x0010 /* include PlaceHolderVars in
* output list */

Definition at line 192 of file optimizer.h.

◆ PVC_INCLUDE_WINDOWFUNCS

#define PVC_INCLUDE_WINDOWFUNCS   0x0004 /* include WindowFuncs in output list */

Definition at line 190 of file optimizer.h.

◆ PVC_RECURSE_AGGREGATES

#define PVC_RECURSE_AGGREGATES   0x0002 /* recurse into Aggref arguments */

Definition at line 189 of file optimizer.h.

◆ PVC_RECURSE_PLACEHOLDERS

#define PVC_RECURSE_PLACEHOLDERS
Value:
0x0020 /* recurse into PlaceHolderVar
* arguments */

Definition at line 193 of file optimizer.h.

◆ PVC_RECURSE_WINDOWFUNCS

#define PVC_RECURSE_WINDOWFUNCS   0x0008 /* recurse into WindowFunc arguments */

Definition at line 191 of file optimizer.h.

Typedef Documentation

◆ ExplainState

typedef struct ExplainState ExplainState

Definition at line 27 of file optimizer.h.

◆ HeapTuple

typedef struct HeapTupleData* HeapTuple

Definition at line 42 of file optimizer.h.

◆ IndexOptInfo

typedef struct IndexOptInfo IndexOptInfo

Definition at line 36 of file optimizer.h.

◆ ParamListInfo

Definition at line 41 of file optimizer.h.

◆ PlannedStmt

typedef struct PlannedStmt PlannedStmt

Definition at line 40 of file optimizer.h.

◆ PlannerInfo

typedef struct PlannerInfo PlannerInfo

Definition at line 35 of file optimizer.h.

◆ SpecialJoinInfo

Definition at line 37 of file optimizer.h.

Enumeration Type Documentation

◆ DebugParallelMode

Enumerator
DEBUG_PARALLEL_OFF 
DEBUG_PARALLEL_ON 
DEBUG_PARALLEL_REGRESS 

Definition at line 94 of file optimizer.h.

95{
DebugParallelMode
Definition: optimizer.h:95
@ DEBUG_PARALLEL_REGRESS
Definition: optimizer.h:98
@ DEBUG_PARALLEL_ON
Definition: optimizer.h:97
@ DEBUG_PARALLEL_OFF
Definition: optimizer.h:96

Function Documentation

◆ canonicalize_qual()

Expr * canonicalize_qual ( Expr qual,
bool  is_check 
)

Definition at line 293 of file prepqual.c.

294{
295 Expr *newqual;
296
297 /* Quick exit for empty qual */
298 if (qual == NULL)
299 return NULL;
300
301 /* This should not be invoked on quals in implicit-AND format */
302 Assert(!IsA(qual, List));
303
304 /*
305 * Pull up redundant subclauses in OR-of-AND trees. We do this only
306 * within the top-level AND/OR structure; there's no point in looking
307 * deeper. Also remove any NULL constants in the top-level structure.
308 */
309 newqual = find_duplicate_ors(qual, is_check);
310
311 return newqual;
312}
Assert(PointerIsAligned(start, uint64))
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
static Expr * find_duplicate_ors(Expr *qual, bool is_check)
Definition: prepqual.c:406
Definition: pg_list.h:54

References Assert(), find_duplicate_ors(), and IsA.

Referenced by ConstraintImpliedByRelConstraint(), convert_EXISTS_to_ANY(), DoCopy(), get_proposed_default_constraint(), get_relation_constraints(), preprocess_expression(), and RelationGetIndexPredicate().

◆ clamp_row_est()

double clamp_row_est ( double  nrows)

Definition at line 213 of file costsize.c.

214{
215 /*
216 * Avoid infinite and NaN row estimates. Costs derived from such values
217 * are going to be useless. Also force the estimate to be at least one
218 * row, to make explain output look better and to avoid possible
219 * divide-by-zero when interpolating costs. Make it an integer, too.
220 */
221 if (nrows > MAXIMUM_ROWCOUNT || isnan(nrows))
222 nrows = MAXIMUM_ROWCOUNT;
223 else if (nrows <= 1.0)
224 nrows = 1.0;
225 else
226 nrows = rint(nrows);
227
228 return nrows;
229}
#define MAXIMUM_ROWCOUNT
Definition: costsize.c:128

References MAXIMUM_ROWCOUNT.

Referenced by adjust_limit_rows_costs(), approx_tuple_count(), bernoulli_samplescangetsamplesize(), calc_joinrel_size_estimate(), compute_bitmap_pages(), compute_gather_rows(), cost_agg(), cost_append(), cost_bitmap_heap_scan(), cost_group(), cost_index(), cost_seqscan(), cost_subplan(), cost_subqueryscan(), cost_tidrangescan(), create_bitmap_subplan(), create_memoize_path(), estimate_array_length(), estimate_hash_bucket_stats(), estimate_num_groups(), estimate_path_cost_size(), estimate_size(), expression_returns_set_rows(), final_cost_hashjoin(), final_cost_mergejoin(), final_cost_nestloop(), get_parameterized_baserel_size(), get_variable_numdistinct(), get_windowclause_startup_tuples(), initial_cost_mergejoin(), set_baserel_size_estimates(), set_cte_size_estimates(), set_foreign_size(), system_rows_samplescangetsamplesize(), system_samplescangetsamplesize(), system_time_samplescangetsamplesize(), and table_block_relation_estimate_size().

◆ clamp_width_est()

int32 clamp_width_est ( int64  tuple_width)

Definition at line 242 of file costsize.c.

243{
244 /*
245 * Anything more than MaxAllocSize is clearly bogus, since we could not
246 * create a tuple that large.
247 */
248 if (tuple_width > MaxAllocSize)
249 return (int32) MaxAllocSize;
250
251 /*
252 * Unlike clamp_row_est, we just Assert that the value isn't negative,
253 * rather than masking such errors.
254 */
255 Assert(tuple_width >= 0);
256
257 return (int32) tuple_width;
258}
int32_t int32
Definition: c.h:548
#define MaxAllocSize
Definition: fe_memutils.h:22

References Assert(), and MaxAllocSize.

Referenced by add_placeholders_to_joinrel(), build_joinrel_tlist(), create_one_window_path(), get_rel_data_width(), set_pathtarget_cost_width(), and set_rel_width().

◆ clause_selectivity()

Selectivity clause_selectivity ( PlannerInfo root,
Node clause,
int  varRelid,
JoinType  jointype,
SpecialJoinInfo sjinfo 
)

Definition at line 667 of file clausesel.c.

672{
673 return clause_selectivity_ext(root, clause, varRelid,
674 jointype, sjinfo, true);
675}
Selectivity clause_selectivity_ext(PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
Definition: clausesel.c:684
tree ctl root
Definition: radixtree.h:1857

References clause_selectivity_ext(), and root.

Referenced by approx_tuple_count(), booltestsel(), consider_new_or_clause(), and get_foreign_key_join_selectivity().

◆ clause_selectivity_ext()

Selectivity clause_selectivity_ext ( PlannerInfo root,
Node clause,
int  varRelid,
JoinType  jointype,
SpecialJoinInfo sjinfo,
bool  use_extended_stats 
)

Definition at line 684 of file clausesel.c.

690{
691 Selectivity s1 = 0.5; /* default for any unhandled clause type */
692 RestrictInfo *rinfo = NULL;
693 bool cacheable = false;
694
695 if (clause == NULL) /* can this still happen? */
696 return s1;
697
698 if (IsA(clause, RestrictInfo))
699 {
700 rinfo = (RestrictInfo *) clause;
701
702 /*
703 * If the clause is marked pseudoconstant, then it will be used as a
704 * gating qual and should not affect selectivity estimates; hence
705 * return 1.0. The only exception is that a constant FALSE may be
706 * taken as having selectivity 0.0, since it will surely mean no rows
707 * out of the plan. This case is simple enough that we need not
708 * bother caching the result.
709 */
710 if (rinfo->pseudoconstant)
711 {
712 if (!IsA(rinfo->clause, Const))
713 return (Selectivity) 1.0;
714 }
715
716 /*
717 * If possible, cache the result of the selectivity calculation for
718 * the clause. We can cache if varRelid is zero or the clause
719 * contains only vars of that relid --- otherwise varRelid will affect
720 * the result, so mustn't cache. Outer join quals might be examined
721 * with either their join's actual jointype or JOIN_INNER, so we need
722 * two cache variables to remember both cases. Note: we assume the
723 * result won't change if we are switching the input relations or
724 * considering a unique-ified case, so we only need one cache variable
725 * for all non-JOIN_INNER cases.
726 */
727 if (varRelid == 0 ||
728 rinfo->num_base_rels == 0 ||
729 (rinfo->num_base_rels == 1 &&
730 bms_is_member(varRelid, rinfo->clause_relids)))
731 {
732 /* Cacheable --- do we already have the result? */
733 if (jointype == JOIN_INNER)
734 {
735 if (rinfo->norm_selec >= 0)
736 return rinfo->norm_selec;
737 }
738 else
739 {
740 if (rinfo->outer_selec >= 0)
741 return rinfo->outer_selec;
742 }
743 cacheable = true;
744 }
745
746 /*
747 * Proceed with examination of contained clause. If the clause is an
748 * OR-clause, we want to look at the variant with sub-RestrictInfos,
749 * so that per-subclause selectivities can be cached.
750 */
751 if (rinfo->orclause)
752 clause = (Node *) rinfo->orclause;
753 else
754 clause = (Node *) rinfo->clause;
755 }
756
757 if (IsA(clause, Var))
758 {
759 Var *var = (Var *) clause;
760
761 /*
762 * We probably shouldn't ever see an uplevel Var here, but if we do,
763 * return the default selectivity...
764 */
765 if (var->varlevelsup == 0 &&
766 (varRelid == 0 || varRelid == (int) var->varno))
767 {
768 /* Use the restriction selectivity function for a bool Var */
769 s1 = boolvarsel(root, (Node *) var, varRelid);
770 }
771 }
772 else if (IsA(clause, Const))
773 {
774 /* bool constant is pretty easy... */
775 Const *con = (Const *) clause;
776
777 s1 = con->constisnull ? 0.0 :
778 DatumGetBool(con->constvalue) ? 1.0 : 0.0;
779 }
780 else if (IsA(clause, Param))
781 {
782 /* see if we can replace the Param */
783 Node *subst = estimate_expression_value(root, clause);
784
785 if (IsA(subst, Const))
786 {
787 /* bool constant is pretty easy... */
788 Const *con = (Const *) subst;
789
790 s1 = con->constisnull ? 0.0 :
791 DatumGetBool(con->constvalue) ? 1.0 : 0.0;
792 }
793 else
794 {
795 /* XXX any way to do better than default? */
796 }
797 }
798 else if (is_notclause(clause))
799 {
800 /* inverse of the selectivity of the underlying clause */
802 (Node *) get_notclausearg((Expr *) clause),
803 varRelid,
804 jointype,
805 sjinfo,
806 use_extended_stats);
807 }
808 else if (is_andclause(clause))
809 {
810 /* share code with clauselist_selectivity() */
812 ((BoolExpr *) clause)->args,
813 varRelid,
814 jointype,
815 sjinfo,
816 use_extended_stats);
817 }
818 else if (is_orclause(clause))
819 {
820 /*
821 * Almost the same thing as clauselist_selectivity, but with the
822 * clauses connected by OR.
823 */
825 ((BoolExpr *) clause)->args,
826 varRelid,
827 jointype,
828 sjinfo,
829 use_extended_stats);
830 }
831 else if (is_opclause(clause) || IsA(clause, DistinctExpr))
832 {
833 OpExpr *opclause = (OpExpr *) clause;
834 Oid opno = opclause->opno;
835
836 if (treat_as_join_clause(root, clause, rinfo, varRelid, sjinfo))
837 {
838 /* Estimate selectivity for a join clause. */
839 s1 = join_selectivity(root, opno,
840 opclause->args,
841 opclause->inputcollid,
842 jointype,
843 sjinfo);
844 }
845 else
846 {
847 /* Estimate selectivity for a restriction clause. */
849 opclause->args,
850 opclause->inputcollid,
851 varRelid);
852 }
853
854 /*
855 * DistinctExpr has the same representation as OpExpr, but the
856 * contained operator is "=" not "<>", so we must negate the result.
857 * This estimation method doesn't give the right behavior for nulls,
858 * but it's better than doing nothing.
859 */
860 if (IsA(clause, DistinctExpr))
861 s1 = 1.0 - s1;
862 }
863 else if (is_funcclause(clause))
864 {
865 FuncExpr *funcclause = (FuncExpr *) clause;
866
867 /* Try to get an estimate from the support function, if any */
869 funcclause->funcid,
870 funcclause->args,
871 funcclause->inputcollid,
872 treat_as_join_clause(root, clause, rinfo,
873 varRelid, sjinfo),
874 varRelid,
875 jointype,
876 sjinfo);
877
878 /* If no support, fall back on boolvarsel */
879 if (s1 < 0)
880 s1 = boolvarsel(root, clause, varRelid);
881 }
882 else if (IsA(clause, ScalarArrayOpExpr))
883 {
884 /* Use node specific selectivity calculation function */
886 (ScalarArrayOpExpr *) clause,
887 treat_as_join_clause(root, clause, rinfo,
888 varRelid, sjinfo),
889 varRelid,
890 jointype,
891 sjinfo);
892 }
893 else if (IsA(clause, RowCompareExpr))
894 {
895 /* Use node specific selectivity calculation function */
897 (RowCompareExpr *) clause,
898 varRelid,
899 jointype,
900 sjinfo);
901 }
902 else if (IsA(clause, NullTest))
903 {
904 /* Use node specific selectivity calculation function */
906 ((NullTest *) clause)->nulltesttype,
907 (Node *) ((NullTest *) clause)->arg,
908 varRelid,
909 jointype,
910 sjinfo);
911 }
912 else if (IsA(clause, BooleanTest))
913 {
914 /* Use node specific selectivity calculation function */
916 ((BooleanTest *) clause)->booltesttype,
917 (Node *) ((BooleanTest *) clause)->arg,
918 varRelid,
919 jointype,
920 sjinfo);
921 }
922 else if (IsA(clause, CurrentOfExpr))
923 {
924 /* CURRENT OF selects at most one row of its table */
925 CurrentOfExpr *cexpr = (CurrentOfExpr *) clause;
926 RelOptInfo *crel = find_base_rel(root, cexpr->cvarno);
927
928 if (crel->tuples > 0)
929 s1 = 1.0 / crel->tuples;
930 }
931 else if (IsA(clause, RelabelType))
932 {
933 /* Not sure this case is needed, but it can't hurt */
935 (Node *) ((RelabelType *) clause)->arg,
936 varRelid,
937 jointype,
938 sjinfo,
939 use_extended_stats);
940 }
941 else if (IsA(clause, CoerceToDomain))
942 {
943 /* Not sure this case is needed, but it can't hurt */
945 (Node *) ((CoerceToDomain *) clause)->arg,
946 varRelid,
947 jointype,
948 sjinfo,
949 use_extended_stats);
950 }
951 else
952 {
953 /*
954 * For anything else, see if we can consider it as a boolean variable.
955 * This only works if it's an immutable expression in Vars of a single
956 * relation; but there's no point in us checking that here because
957 * boolvarsel() will do it internally, and return a suitable default
958 * selectivity if not.
959 */
960 s1 = boolvarsel(root, clause, varRelid);
961 }
962
963 /* Cache the result if possible */
964 if (cacheable)
965 {
966 if (jointype == JOIN_INNER)
967 rinfo->norm_selec = s1;
968 else
969 rinfo->outer_selec = s1;
970 }
971
972#ifdef SELECTIVITY_DEBUG
973 elog(DEBUG4, "clause_selectivity: s1 %f", s1);
974#endif /* SELECTIVITY_DEBUG */
975
976 return s1;
977}
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition: clauses.c:2411
Selectivity clauselist_selectivity_ext(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
Definition: clausesel.c:117
static bool treat_as_join_clause(PlannerInfo *root, Node *clause, RestrictInfo *rinfo, int varRelid, SpecialJoinInfo *sjinfo)
Definition: clausesel.c:586
static Selectivity clauselist_selectivity_or(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
Definition: clausesel.c:359
#define elog(elevel,...)
Definition: elog.h:226
#define DEBUG4
Definition: elog.h:27
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:107
static bool is_orclause(const void *clause)
Definition: nodeFuncs.h:116
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:76
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:69
static bool is_notclause(const void *clause)
Definition: nodeFuncs.h:125
static Expr * get_notclausearg(const void *notclause)
Definition: nodeFuncs.h:134
double Selectivity
Definition: nodes.h:260
@ JOIN_INNER
Definition: nodes.h:303
void * arg
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
Definition: plancat.c:2224
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: plancat.c:2263
Selectivity function_selectivity(PlannerInfo *root, Oid funcid, List *args, Oid inputcollid, bool is_join, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: plancat.c:2303
static bool DatumGetBool(Datum X)
Definition: postgres.h:100
unsigned int Oid
Definition: postgres_ext.h:32
char * s1
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition: relnode.c:529
Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1624
Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1782
Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
Definition: selfuncs.c:1585
Selectivity scalararraysel(PlannerInfo *root, ScalarArrayOpExpr *clause, bool is_join_clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:1900
Selectivity rowcomparesel(PlannerInfo *root, RowCompareExpr *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition: selfuncs.c:2289
Oid funcid
Definition: primnodes.h:782
List * args
Definition: primnodes.h:800
Definition: nodes.h:135
Oid opno
Definition: primnodes.h:850
List * args
Definition: primnodes.h:868
Cardinality tuples
Definition: pathnodes.h:1000
Expr * clause
Definition: pathnodes.h:2792
Definition: primnodes.h:262
int varno
Definition: primnodes.h:269
Index varlevelsup
Definition: primnodes.h:294

References arg, generate_unaccent_rules::args, FuncExpr::args, OpExpr::args, bms_is_member(), booltestsel(), boolvarsel(), RestrictInfo::clause, clause_selectivity_ext(), clauselist_selectivity_ext(), clauselist_selectivity_or(), CurrentOfExpr::cvarno, DatumGetBool(), DEBUG4, elog, estimate_expression_value(), find_base_rel(), FuncExpr::funcid, function_selectivity(), get_notclausearg(), is_andclause(), is_funcclause(), is_notclause(), is_opclause(), is_orclause(), IsA, JOIN_INNER, join_selectivity(), nulltestsel(), OpExpr::opno, restriction_selectivity(), root, rowcomparesel(), s1, scalararraysel(), treat_as_join_clause(), RelOptInfo::tuples, and RangeQueryClause::var.

Referenced by clause_selectivity(), clause_selectivity_ext(), clauselist_selectivity_ext(), clauselist_selectivity_or(), and statext_mcv_clauselist_selectivity().

◆ clauselist_selectivity()

◆ clauselist_selectivity_ext()

Selectivity clauselist_selectivity_ext ( PlannerInfo root,
List clauses,
int  varRelid,
JoinType  jointype,
SpecialJoinInfo sjinfo,
bool  use_extended_stats 
)

Definition at line 117 of file clausesel.c.

123{
124 Selectivity s1 = 1.0;
125 RelOptInfo *rel;
126 Bitmapset *estimatedclauses = NULL;
127 RangeQueryClause *rqlist = NULL;
128 ListCell *l;
129 int listidx;
130
131 /*
132 * If there's exactly one clause, just go directly to
133 * clause_selectivity_ext(). None of what we might do below is relevant.
134 */
135 if (list_length(clauses) == 1)
136 return clause_selectivity_ext(root, (Node *) linitial(clauses),
137 varRelid, jointype, sjinfo,
138 use_extended_stats);
139
140 /*
141 * Determine if these clauses reference a single relation. If so, and if
142 * it has extended statistics, try to apply those.
143 */
144 rel = find_single_rel_for_clauses(root, clauses);
145 if (use_extended_stats && rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
146 {
147 /*
148 * Estimate as many clauses as possible using extended statistics.
149 *
150 * 'estimatedclauses' is populated with the 0-based list position
151 * index of clauses estimated here, and that should be ignored below.
152 */
153 s1 = statext_clauselist_selectivity(root, clauses, varRelid,
154 jointype, sjinfo, rel,
155 &estimatedclauses, false);
156 }
157
158 /*
159 * Apply normal selectivity estimates for remaining clauses. We'll be
160 * careful to skip any clauses which were already estimated above.
161 *
162 * Anything that doesn't look like a potential rangequery clause gets
163 * multiplied into s1 and forgotten. Anything that does gets inserted into
164 * an rqlist entry.
165 */
166 listidx = -1;
167 foreach(l, clauses)
168 {
169 Node *clause = (Node *) lfirst(l);
170 RestrictInfo *rinfo;
172
173 listidx++;
174
175 /*
176 * Skip this clause if it's already been estimated by some other
177 * statistics above.
178 */
179 if (bms_is_member(listidx, estimatedclauses))
180 continue;
181
182 /* Compute the selectivity of this clause in isolation */
183 s2 = clause_selectivity_ext(root, clause, varRelid, jointype, sjinfo,
184 use_extended_stats);
185
186 /*
187 * Check for being passed a RestrictInfo.
188 *
189 * If it's a pseudoconstant RestrictInfo, then s2 is either 1.0 or
190 * 0.0; just use that rather than looking for range pairs.
191 */
192 if (IsA(clause, RestrictInfo))
193 {
194 rinfo = (RestrictInfo *) clause;
195 if (rinfo->pseudoconstant)
196 {
197 s1 = s1 * s2;
198 continue;
199 }
200 clause = (Node *) rinfo->clause;
201 }
202 else
203 rinfo = NULL;
204
205 /*
206 * See if it looks like a restriction clause with a pseudoconstant on
207 * one side. (Anything more complicated than that might not behave in
208 * the simple way we are expecting.) Most of the tests here can be
209 * done more efficiently with rinfo than without.
210 */
211 if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
212 {
213 OpExpr *expr = (OpExpr *) clause;
214 bool varonleft = true;
215 bool ok;
216
217 if (rinfo)
218 {
219 ok = (rinfo->num_base_rels == 1) &&
221 rinfo->right_relids) ||
222 (varonleft = false,
224 rinfo->left_relids)));
225 }
226 else
227 {
228 ok = (NumRelids(root, clause) == 1) &&
230 (varonleft = false,
232 }
233
234 if (ok)
235 {
236 /*
237 * If it's not a "<"/"<="/">"/">=" operator, just merge the
238 * selectivity in generically. But if it's the right oprrest,
239 * add the clause to rqlist for later processing.
240 */
241 switch (get_oprrest(expr->opno))
242 {
243 case F_SCALARLTSEL:
244 case F_SCALARLESEL:
245 addRangeClause(&rqlist, clause,
246 varonleft, true, s2);
247 break;
248 case F_SCALARGTSEL:
249 case F_SCALARGESEL:
250 addRangeClause(&rqlist, clause,
251 varonleft, false, s2);
252 break;
253 default:
254 /* Just merge the selectivity in generically */
255 s1 = s1 * s2;
256 break;
257 }
258 continue; /* drop to loop bottom */
259 }
260 }
261
262 /* Not the right form, so treat it generically. */
263 s1 = s1 * s2;
264 }
265
266 /*
267 * Now scan the rangequery pair list.
268 */
269 while (rqlist != NULL)
270 {
271 RangeQueryClause *rqnext;
272
273 if (rqlist->have_lobound && rqlist->have_hibound)
274 {
275 /* Successfully matched a pair of range clauses */
277
278 /*
279 * Exact equality to the default value probably means the
280 * selectivity function punted. This is not airtight but should
281 * be good enough.
282 */
283 if (rqlist->hibound == DEFAULT_INEQ_SEL ||
284 rqlist->lobound == DEFAULT_INEQ_SEL)
285 {
287 }
288 else
289 {
290 s2 = rqlist->hibound + rqlist->lobound - 1.0;
291
292 /* Adjust for double-exclusion of NULLs */
293 s2 += nulltestsel(root, IS_NULL, rqlist->var,
294 varRelid, jointype, sjinfo);
295
296 /*
297 * A zero or slightly negative s2 should be converted into a
298 * small positive value; we probably are dealing with a very
299 * tight range and got a bogus result due to roundoff errors.
300 * However, if s2 is very negative, then we probably have
301 * default selectivity estimates on one or both sides of the
302 * range that we failed to recognize above for some reason.
303 */
304 if (s2 <= 0.0)
305 {
306 if (s2 < -0.01)
307 {
308 /*
309 * No data available --- use a default estimate that
310 * is small, but not real small.
311 */
313 }
314 else
315 {
316 /*
317 * It's just roundoff error; use a small positive
318 * value
319 */
320 s2 = 1.0e-10;
321 }
322 }
323 }
324 /* Merge in the selectivity of the pair of clauses */
325 s1 *= s2;
326 }
327 else
328 {
329 /* Only found one of a pair, merge it in generically */
330 if (rqlist->have_lobound)
331 s1 *= rqlist->lobound;
332 else
333 s1 *= rqlist->hibound;
334 }
335 /* release storage and advance */
336 rqnext = rqlist->next;
337 pfree(rqlist);
338 rqlist = rqnext;
339 }
340
341 return s1;
342}
int NumRelids(PlannerInfo *root, Node *clause)
Definition: clauses.c:2145
bool is_pseudo_constant_clause(Node *clause)
Definition: clauses.c:2103
bool is_pseudo_constant_clause_relids(Node *clause, Relids relids)
Definition: clauses.c:2123
static void addRangeClause(RangeQueryClause **rqlist, Node *clause, bool varonleft, bool isLTsel, Selectivity s2)
Definition: clausesel.c:427
static RelOptInfo * find_single_rel_for_clauses(PlannerInfo *root, List *clauses)
Definition: clausesel.c:523
Selectivity statext_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses, bool is_or)
RegProcedure get_oprrest(Oid opno)
Definition: lsyscache.c:1707
void pfree(void *pointer)
Definition: mcxt.c:1616
@ RTE_RELATION
Definition: parsenodes.h:1070
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
char * s2
@ IS_NULL
Definition: primnodes.h:1977
#define DEFAULT_RANGE_INEQ_SEL
Definition: selfuncs.h:40
#define DEFAULT_INEQ_SEL
Definition: selfuncs.h:37
Selectivity hibound
Definition: clausesel.c:38
Selectivity lobound
Definition: clausesel.c:37
struct RangeQueryClause * next
Definition: clausesel.c:33
List * statlist
Definition: pathnodes.h:997
RTEKind rtekind
Definition: pathnodes.h:977

References addRangeClause(), generate_unaccent_rules::args, OpExpr::args, bms_is_member(), RestrictInfo::clause, clause_selectivity_ext(), DEFAULT_INEQ_SEL, DEFAULT_RANGE_INEQ_SEL, find_single_rel_for_clauses(), get_oprrest(), RangeQueryClause::have_hibound, RangeQueryClause::have_lobound, RangeQueryClause::hibound, IS_NULL, is_opclause(), is_pseudo_constant_clause(), is_pseudo_constant_clause_relids(), IsA, lfirst, linitial, list_length(), RangeQueryClause::lobound, lsecond, RangeQueryClause::next, NIL, nulltestsel(), NumRelids(), OpExpr::opno, pfree(), root, RTE_RELATION, RelOptInfo::rtekind, s1, s2, statext_clauselist_selectivity(), RelOptInfo::statlist, and RangeQueryClause::var.

Referenced by clause_selectivity_ext(), clauselist_apply_dependencies(), clauselist_selectivity(), and statext_mcv_clauselist_selectivity().

◆ contain_mutable_functions()

◆ contain_mutable_functions_after_planning()

bool contain_mutable_functions_after_planning ( Expr expr)

Definition at line 502 of file clauses.c.

503{
504 /* We assume here that expression_planner() won't scribble on its input */
505 expr = expression_planner(expr);
506
507 /* Now we can search for non-immutable functions */
508 return contain_mutable_functions((Node *) expr);
509}
bool contain_mutable_functions(Node *clause)
Definition: clauses.c:382
Expr * expression_planner(Expr *expr)
Definition: planner.c:6764

References contain_mutable_functions(), and expression_planner().

Referenced by CheckPredicate(), ComputeIndexAttrs(), and cookDefault().

◆ contain_var_clause()

◆ contain_vars_of_level()

bool contain_vars_of_level ( Node node,
int  levelsup 
)

◆ contain_vars_returning_old_or_new()

bool contain_vars_returning_old_or_new ( Node node)

Definition at line 511 of file var.c.

512{
514}
static bool contain_vars_returning_old_or_new_walker(Node *node, void *context)
Definition: var.c:517

References contain_vars_returning_old_or_new_walker().

Referenced by make_modifytable().

◆ contain_volatile_functions()

bool contain_volatile_functions ( Node clause)

Definition at line 550 of file clauses.c.

551{
552 return contain_volatile_functions_walker(clause, NULL);
553}
static bool contain_volatile_functions_walker(Node *node, void *context)
Definition: clauses.c:562

References contain_volatile_functions_walker().

Referenced by apply_child_basequals(), ATExecAddColumn(), check_hashjoinable(), check_mergejoinable(), check_output_expressions(), compute_semijoin_info(), contain_volatile_functions_after_planning(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), convert_EXISTS_to_ANY(), convert_VALUES_to_ANY(), CopyFrom(), distribute_qual_to_rels(), estimate_num_groups(), ExecInitWindowAgg(), expand_indexqual_rowcompare(), find_compatible_agg(), find_simplified_clause(), get_eclass_for_sort_expr(), get_memoize_path(), group_similar_or_args(), initialize_peragg(), inline_function(), inline_function_in_from(), is_pseudo_constant_clause(), is_pseudo_constant_clause_relids(), is_pseudo_constant_for_index(), is_safe_restriction_clause_for(), is_simple_subquery(), is_simple_values(), IsBinaryTidClause(), IsTidEqualAnyClause(), make_sort_input_target(), mark_nullable_by_grouping(), match_clause_to_ordering_op(), match_clause_to_partition_key(), match_opclause_to_indexcol(), match_orclause_to_indexcol(), match_rowcompare_to_indexcol(), match_saopclause_to_indexcol(), paraminfo_get_equal_hashops(), qual_is_pushdown_safe(), remove_unused_subquery_outputs(), SS_process_ctes(), and subquery_planner().

◆ contain_volatile_functions_after_planning()

bool contain_volatile_functions_after_planning ( Expr expr)

Definition at line 671 of file clauses.c.

672{
673 /* We assume here that expression_planner() won't scribble on its input */
674 expr = expression_planner(expr);
675
676 /* Now we can search for volatile functions */
677 return contain_volatile_functions((Node *) expr);
678}
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:550

References contain_volatile_functions(), and expression_planner().

◆ contain_volatile_functions_not_nextval()

bool contain_volatile_functions_not_nextval ( Node clause)

Definition at line 685 of file clauses.c.

686{
688}
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition: clauses.c:698

References contain_volatile_functions_not_nextval_walker().

Referenced by BeginCopyFrom().

◆ convert_saop_to_hashed_saop()

void convert_saop_to_hashed_saop ( Node node)

Definition at line 2303 of file clauses.c.

2304{
2305 (void) convert_saop_to_hashed_saop_walker(node, NULL);
2306}
static bool convert_saop_to_hashed_saop_walker(Node *node, void *context)
Definition: clauses.c:2309

References convert_saop_to_hashed_saop_walker().

Referenced by preprocess_expression().

◆ count_nonjunk_tlist_entries()

int count_nonjunk_tlist_entries ( List tlist)

Definition at line 195 of file tlist.c.

196{
197 int len = 0;
198 ListCell *l;
199
200 foreach(l, tlist)
201 {
202 TargetEntry *tle = (TargetEntry *) lfirst(l);
203
204 if (!tle->resjunk)
205 len++;
206 }
207 return len;
208}
const void size_t len

References len, and lfirst.

Referenced by get_update_query_targetlist_def(), transformJsonArrayQueryConstructor(), transformMultiAssignRef(), and transformSubLink().

◆ estimate_expression_value()

Node * estimate_expression_value ( PlannerInfo root,
Node node 
)

Definition at line 2411 of file clauses.c.

2412{
2414
2415 context.boundParams = root->glob->boundParams; /* bound Params */
2416 /* we do not need to mark the plan as depending on inlined functions */
2417 context.root = NULL;
2418 context.active_fns = NIL; /* nothing being recursively simplified */
2419 context.case_val = NULL; /* no CASE being examined */
2420 context.estimate = true; /* unsafe transformations OK */
2421 return eval_const_expressions_mutator(node, &context);
2422}
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition: clauses.c:2456
ParamListInfo boundParams
Definition: clauses.c:66

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

Referenced by array_unnest_support(), bernoulli_samplescangetsamplesize(), clause_selectivity_ext(), generate_series_int4_support(), generate_series_int8_support(), generate_series_numeric_support(), generate_series_timestamp_support(), get_restriction_variable(), gincost_opexpr(), gincost_scalararrayopexpr(), preprocess_limit(), scalararraysel(), system_rows_samplescangetsamplesize(), system_samplescangetsamplesize(), and system_time_samplescangetsamplesize().

◆ eval_const_expressions()

Node * eval_const_expressions ( PlannerInfo root,
Node node 
)

◆ evaluate_expr()

Expr * evaluate_expr ( Expr expr,
Oid  result_type,
int32  result_typmod,
Oid  result_collation 
)

Definition at line 5287 of file clauses.c.

5289{
5290 EState *estate;
5291 ExprState *exprstate;
5292 MemoryContext oldcontext;
5293 Datum const_val;
5294 bool const_is_null;
5295 int16 resultTypLen;
5296 bool resultTypByVal;
5297
5298 /*
5299 * To use the executor, we need an EState.
5300 */
5301 estate = CreateExecutorState();
5302
5303 /* We can use the estate's working context to avoid memory leaks. */
5304 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5305
5306 /* Make sure any opfuncids are filled in. */
5307 fix_opfuncids((Node *) expr);
5308
5309 /*
5310 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5311 * because it'd result in recursively invoking eval_const_expressions.)
5312 */
5313 exprstate = ExecInitExpr(expr, NULL);
5314
5315 /*
5316 * And evaluate it.
5317 *
5318 * It is OK to use a default econtext because none of the ExecEvalExpr()
5319 * code used in this situation will use econtext. That might seem
5320 * fortuitous, but it's not so unreasonable --- a constant expression does
5321 * not depend on context, by definition, n'est ce pas?
5322 */
5323 const_val = ExecEvalExprSwitchContext(exprstate,
5324 GetPerTupleExprContext(estate),
5325 &const_is_null);
5326
5327 /* Get info needed about result datatype */
5328 get_typlenbyval(result_type, &resultTypLen, &resultTypByVal);
5329
5330 /* Get back to outer memory context */
5331 MemoryContextSwitchTo(oldcontext);
5332
5333 /*
5334 * Must copy result out of sub-context used by expression eval.
5335 *
5336 * Also, if it's varlena, forcibly detoast it. This protects us against
5337 * storing TOAST pointers into plans that might outlive the referenced
5338 * data. (makeConst would handle detoasting anyway, but it's worth a few
5339 * extra lines here so that we can do the copy and detoast in one step.)
5340 */
5341 if (!const_is_null)
5342 {
5343 if (resultTypLen == -1)
5344 const_val = PointerGetDatum(PG_DETOAST_DATUM_COPY(const_val));
5345 else
5346 const_val = datumCopy(const_val, resultTypByVal, resultTypLen);
5347 }
5348
5349 /* Release all the junk we just created */
5350 FreeExecutorState(estate);
5351
5352 /*
5353 * Make the constant result node.
5354 */
5355 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5356 resultTypLen,
5357 const_val, const_is_null,
5358 resultTypByVal);
5359}
int16_t int16
Definition: c.h:547
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:143
void FreeExecutorState(EState *estate)
Definition: execUtils.c:192
EState * CreateExecutorState(void)
Definition: execUtils.c:88
#define GetPerTupleExprContext(estate)
Definition: executor.h:656
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:436
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2401
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:350
void fix_opfuncids(Node *node)
Definition: nodeFuncs.c:1840
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:352
uint64_t Datum
Definition: postgres.h:70
MemoryContext es_query_cxt
Definition: execnodes.h:710

References CreateExecutorState(), datumCopy(), EState::es_query_cxt, ExecEvalExprSwitchContext(), ExecInitExpr(), fix_opfuncids(), FreeExecutorState(), get_typlenbyval(), GetPerTupleExprContext, makeConst(), MemoryContextSwitchTo(), PG_DETOAST_DATUM_COPY, and PointerGetDatum().

Referenced by eval_const_expressions_mutator(), evaluate_function(), and transformPartitionBoundValue().

◆ expand_function_arguments()

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

Definition at line 4490 of file clauses.c.

4492{
4493 Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
4494 Oid *proargtypes = funcform->proargtypes.values;
4495 int pronargs = funcform->pronargs;
4496 bool has_named_args = false;
4497 ListCell *lc;
4498
4499 /*
4500 * If we are asked to match to OUT arguments, then use the proallargtypes
4501 * array (which includes those); otherwise use proargtypes (which
4502 * doesn't). Of course, if proallargtypes is null, we always use
4503 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4504 * considering that we may have nothing to do here, but fortunately the
4505 * common case is include_out_arguments == false.)
4506 */
4507 if (include_out_arguments)
4508 {
4509 Datum proallargtypes;
4510 bool isNull;
4511
4512 proallargtypes = SysCacheGetAttr(PROCOID, func_tuple,
4513 Anum_pg_proc_proallargtypes,
4514 &isNull);
4515 if (!isNull)
4516 {
4517 ArrayType *arr = DatumGetArrayTypeP(proallargtypes);
4518
4519 pronargs = ARR_DIMS(arr)[0];
4520 if (ARR_NDIM(arr) != 1 ||
4521 pronargs < 0 ||
4522 ARR_HASNULL(arr) ||
4523 ARR_ELEMTYPE(arr) != OIDOID)
4524 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4525 Assert(pronargs >= funcform->pronargs);
4526 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4527 }
4528 }
4529
4530 /* Do we have any named arguments? */
4531 foreach(lc, args)
4532 {
4533 Node *arg = (Node *) lfirst(lc);
4534
4535 if (IsA(arg, NamedArgExpr))
4536 {
4537 has_named_args = true;
4538 break;
4539 }
4540 }
4541
4542 /* If so, we must apply reorder_function_arguments */
4543 if (has_named_args)
4544 {
4546 /* Recheck argument types and add casts if needed */
4547 recheck_cast_function_args(args, result_type,
4548 proargtypes, pronargs,
4549 func_tuple);
4550 }
4551 else if (list_length(args) < pronargs)
4552 {
4553 /* No named args, but we seem to be short some defaults */
4554 args = add_function_defaults(args, pronargs, func_tuple);
4555 /* Recheck argument types and add casts if needed */
4556 recheck_cast_function_args(args, result_type,
4557 proargtypes, pronargs,
4558 func_tuple);
4559 }
4560
4561 return args;
4562}
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
static List * add_function_defaults(List *args, int pronargs, HeapTuple func_tuple)
Definition: clauses.c:4641
static List * reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple)
Definition: clauses.c:4571
static void recheck_cast_function_args(List *args, Oid result_type, Oid *proargtypes, int pronargs, HeapTuple func_tuple)
Definition: clauses.c:4695
#define ERROR
Definition: elog.h:39
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
int16 pronargs
Definition: pg_proc.h:81
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:595

References add_function_defaults(), arg, generate_unaccent_rules::args, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert(), DatumGetArrayTypeP, elog, ERROR, GETSTRUCT(), IsA, lfirst, list_length(), pronargs, recheck_cast_function_args(), reorder_function_arguments(), and SysCacheGetAttr().

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

◆ expr_is_nonnullable()

bool expr_is_nonnullable ( PlannerInfo root,
Expr expr,
bool  use_rel_info 
)

Definition at line 4348 of file clauses.c.

4349{
4350 /* since this function recurses, it could be driven to stack overflow */
4352
4353 switch (nodeTag(expr))
4354 {
4355 case T_Var:
4356 {
4357 if (root)
4358 return var_is_nonnullable(root, (Var *) expr, use_rel_info);
4359 }
4360 break;
4361 case T_Const:
4362 return !((Const *) expr)->constisnull;
4363 case T_CoalesceExpr:
4364 {
4365 /*
4366 * A CoalesceExpr returns NULL if and only if all its
4367 * arguments are NULL. Therefore, we can determine that a
4368 * CoalesceExpr cannot be NULL if at least one of its
4369 * arguments can be proven non-nullable.
4370 */
4371 CoalesceExpr *coalesceexpr = (CoalesceExpr *) expr;
4372
4373 foreach_ptr(Expr, arg, coalesceexpr->args)
4374 {
4375 if (expr_is_nonnullable(root, arg, use_rel_info))
4376 return true;
4377 }
4378 }
4379 break;
4380 case T_MinMaxExpr:
4381 {
4382 /*
4383 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4384 * its arguments evaluate to NULL.
4385 */
4386 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4387
4388 foreach_ptr(Expr, arg, minmaxexpr->args)
4389 {
4390 if (expr_is_nonnullable(root, arg, use_rel_info))
4391 return true;
4392 }
4393 }
4394 break;
4395 case T_CaseExpr:
4396 {
4397 /*
4398 * A CASE expression is non-nullable if all branch results are
4399 * non-nullable. We must also verify that the default result
4400 * (ELSE) exists and is non-nullable.
4401 */
4402 CaseExpr *caseexpr = (CaseExpr *) expr;
4403
4404 /* The default result must be present and non-nullable */
4405 if (caseexpr->defresult == NULL ||
4406 !expr_is_nonnullable(root, caseexpr->defresult, use_rel_info))
4407 return false;
4408
4409 /* All branch results must be non-nullable */
4410 foreach_ptr(CaseWhen, casewhen, caseexpr->args)
4411 {
4412 if (!expr_is_nonnullable(root, casewhen->result, use_rel_info))
4413 return false;
4414 }
4415
4416 return true;
4417 }
4418 break;
4419 case T_ArrayExpr:
4420 {
4421 /*
4422 * An ARRAY[] expression always returns a valid Array object,
4423 * even if it is empty (ARRAY[]) or contains NULLs
4424 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4425 */
4426 return true;
4427 }
4428 case T_NullTest:
4429 {
4430 /*
4431 * An IS NULL / IS NOT NULL expression always returns a
4432 * boolean value. It never returns SQL NULL.
4433 */
4434 return true;
4435 }
4436 case T_BooleanTest:
4437 {
4438 /*
4439 * A BooleanTest expression always evaluates to a boolean
4440 * value. It never returns SQL NULL.
4441 */
4442 return true;
4443 }
4444 case T_DistinctExpr:
4445 {
4446 /*
4447 * IS DISTINCT FROM never returns NULL, effectively acting as
4448 * though NULL were a normal data value.
4449 */
4450 return true;
4451 }
4452 case T_RelabelType:
4453 {
4454 /*
4455 * RelabelType does not change the nullability of the data.
4456 * The result is non-nullable if and only if the argument is
4457 * non-nullable.
4458 */
4459 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4460 use_rel_info);
4461 }
4462 default:
4463 break;
4464 }
4465
4466 return false;
4467}
bool expr_is_nonnullable(PlannerInfo *root, Expr *expr, bool use_rel_info)
Definition: clauses.c:4348
bool var_is_nonnullable(PlannerInfo *root, Var *var, bool use_rel_info)
Definition: clauses.c:4283
#define nodeTag(nodeptr)
Definition: nodes.h:139
#define foreach_ptr(type, var, lst)
Definition: pg_list.h:469
void check_stack_depth(void)
Definition: stack_depth.c:95
Expr * defresult
Definition: primnodes.h:1348
List * args
Definition: primnodes.h:1347
List * args
Definition: primnodes.h:1517
List * args
Definition: primnodes.h:1543

References arg, CaseExpr::args, CoalesceExpr::args, MinMaxExpr::args, check_stack_depth(), CaseExpr::defresult, expr_is_nonnullable(), foreach_ptr, nodeTag, root, and var_is_nonnullable().

Referenced by eval_const_expressions_mutator(), expr_is_nonnullable(), int8inc_support(), restriction_is_always_false(), and restriction_is_always_true().

◆ expression_planner()

Expr * expression_planner ( Expr expr)

Definition at line 6764 of file planner.c.

6765{
6766 Node *result;
6767
6768 /*
6769 * Convert named-argument function calls, insert default arguments and
6770 * simplify constant subexprs
6771 */
6772 result = eval_const_expressions(NULL, (Node *) expr);
6773
6774 /* Fill in opfuncid values if missing */
6775 fix_opfuncids(result);
6776
6777 return (Expr *) result;
6778}
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2270

References eval_const_expressions(), and fix_opfuncids().

Referenced by ATExecAddColumn(), ATExecSetExpression(), ATPrepAlterColumnType(), BeginCopyFrom(), ComputePartitionAttrs(), contain_mutable_functions_after_planning(), contain_volatile_functions_after_planning(), createTableConstraints(), ExecPrepareCheck(), ExecPrepareExpr(), ExecPrepareQual(), load_domaintype_info(), set_baserel_partition_constraint(), slot_fill_defaults(), and transformPartitionBoundValue().

◆ expression_planner_with_deps()

Expr * expression_planner_with_deps ( Expr expr,
List **  relationOids,
List **  invalItems 
)

Definition at line 6791 of file planner.c.

6794{
6795 Node *result;
6796 PlannerGlobal glob;
6798
6799 /* Make up dummy planner state so we can use setrefs machinery */
6800 MemSet(&glob, 0, sizeof(glob));
6801 glob.type = T_PlannerGlobal;
6802 glob.relationOids = NIL;
6803 glob.invalItems = NIL;
6804
6805 MemSet(&root, 0, sizeof(root));
6806 root.type = T_PlannerInfo;
6807 root.glob = &glob;
6808
6809 /*
6810 * Convert named-argument function calls, insert default arguments and
6811 * simplify constant subexprs. Collect identities of inlined functions
6812 * and elided domains, too.
6813 */
6814 result = eval_const_expressions(&root, (Node *) expr);
6815
6816 /* Fill in opfuncid values if missing */
6817 fix_opfuncids(result);
6818
6819 /*
6820 * Now walk the finished expression to find anything else we ought to
6821 * record as an expression dependency.
6822 */
6823 (void) extract_query_dependencies_walker(result, &root);
6824
6825 *relationOids = glob.relationOids;
6826 *invalItems = glob.invalItems;
6827
6828 return (Expr *) result;
6829}
#define MemSet(start, val, len)
Definition: c.h:1019
bool extract_query_dependencies_walker(Node *node, PlannerInfo *context)
Definition: setrefs.c:3692
List * invalItems
Definition: pathnodes.h:154
List * relationOids
Definition: pathnodes.h:151

References eval_const_expressions(), extract_query_dependencies_walker(), fix_opfuncids(), PlannerGlobal::invalItems, MemSet, NIL, PlannerGlobal::relationOids, and root.

Referenced by GetCachedExpression().

◆ extract_query_dependencies()

void extract_query_dependencies ( Node query,
List **  relationOids,
List **  invalItems,
bool *  hasRowSecurity 
)

Definition at line 3656 of file setrefs.c.

3660{
3661 PlannerGlobal glob;
3663
3664 /* Make up dummy planner state so we can use this module's machinery */
3665 MemSet(&glob, 0, sizeof(glob));
3666 glob.type = T_PlannerGlobal;
3667 glob.relationOids = NIL;
3668 glob.invalItems = NIL;
3669 /* Hack: we use glob.dependsOnRole to collect hasRowSecurity flags */
3670 glob.dependsOnRole = false;
3671
3672 MemSet(&root, 0, sizeof(root));
3673 root.type = T_PlannerInfo;
3674 root.glob = &glob;
3675
3677
3678 *relationOids = glob.relationOids;
3679 *invalItems = glob.invalItems;
3680 *hasRowSecurity = glob.dependsOnRole;
3681}
bool dependsOnRole
Definition: pathnodes.h:172

References PlannerGlobal::dependsOnRole, extract_query_dependencies_walker(), PlannerGlobal::invalItems, MemSet, NIL, PlannerGlobal::relationOids, and root.

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ flatten_group_exprs()

Node * flatten_group_exprs ( PlannerInfo root,
Query query,
Node node 
)

Definition at line 968 of file var.c.

969{
971
972 /*
973 * We do not expect this to be applied to the whole Query, only to
974 * expressions or LATERAL subqueries. Hence, if the top node is a Query,
975 * it's okay to immediately increment sublevels_up.
976 */
977 Assert(node != (Node *) query);
978
979 context.root = root;
980 context.query = query;
981 context.sublevels_up = 0;
982 /* flag whether grouping expressions could possibly contain SubLinks */
983 context.possible_sublink = query->hasSubLinks;
984 /* if hasSubLinks is already true, no need to work hard */
985 context.inserted_sublink = query->hasSubLinks;
986
987 return flatten_group_exprs_mutator(node, &context);
988}
PlannerInfo * root
Definition: var.c:66
static Node * flatten_group_exprs_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition: var.c:991

References Assert(), flatten_group_exprs_mutator(), flatten_join_alias_vars_context::inserted_sublink, flatten_join_alias_vars_context::possible_sublink, flatten_join_alias_vars_context::query, flatten_join_alias_vars_context::root, root, and flatten_join_alias_vars_context::sublevels_up.

Referenced by get_query_def(), and subquery_planner().

◆ flatten_join_alias_vars()

Node * flatten_join_alias_vars ( PlannerInfo root,
Query query,
Node node 
)

Definition at line 789 of file var.c.

790{
792
793 /*
794 * We do not expect this to be applied to the whole Query, only to
795 * expressions or LATERAL subqueries. Hence, if the top node is a Query,
796 * it's okay to immediately increment sublevels_up.
797 */
798 Assert(node != (Node *) query);
799
800 context.root = root;
801 context.query = query;
802 context.sublevels_up = 0;
803 /* flag whether join aliases could possibly contain SubLinks */
804 context.possible_sublink = query->hasSubLinks;
805 /* if hasSubLinks is already true, no need to work hard */
806 context.inserted_sublink = query->hasSubLinks;
807
808 return flatten_join_alias_vars_mutator(node, &context);
809}
static Node * flatten_join_alias_vars_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition: var.c:812

References Assert(), flatten_join_alias_vars_mutator(), flatten_join_alias_vars_context::inserted_sublink, flatten_join_alias_vars_context::possible_sublink, flatten_join_alias_vars_context::query, flatten_join_alias_vars_context::root, root, and flatten_join_alias_vars_context::sublevels_up.

Referenced by finalize_grouping_exprs_walker(), parseCheckAggregates(), preprocess_expression(), pull_up_simple_subquery(), and subquery_planner().

◆ get_sortgroupclause_expr()

Node * get_sortgroupclause_expr ( SortGroupClause sgClause,
List targetList 
)

Definition at line 388 of file tlist.c.

389{
390 TargetEntry *tle = get_sortgroupclause_tle(sgClause, targetList);
391
392 return (Node *) tle->expr;
393}
Expr * expr
Definition: primnodes.h:2239
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
Definition: tlist.c:376

References TargetEntry::expr, and get_sortgroupclause_tle().

Referenced by get_sortgrouplist_exprs(), make_pathkeys_for_sortclauses_extended(), transformAggregateCall(), and transformWindowDefinitions().

◆ get_sortgroupclause_tle()

◆ get_sortgrouplist_exprs()

List * get_sortgrouplist_exprs ( List sgClauses,
List targetList 
)

Definition at line 401 of file tlist.c.

402{
403 List *result = NIL;
404 ListCell *l;
405
406 foreach(l, sgClauses)
407 {
408 SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
409 Node *sortexpr;
410
411 sortexpr = get_sortgroupclause_expr(sortcl, targetList);
412 result = lappend(result, sortexpr);
413 }
414 return result;
415}
List * lappend(List *list, void *datum)
Definition: list.c:339
Node * get_sortgroupclause_expr(SortGroupClause *sgClause, List *targetList)
Definition: tlist.c:388

References get_sortgroupclause_expr(), lappend(), lfirst, and NIL.

Referenced by create_final_distinct_paths(), create_partial_distinct_paths(), estimate_path_cost_size(), get_number_of_groups(), get_windowclause_startup_tuples(), and group_by_has_partkey().

◆ get_sortgroupref_clause()

SortGroupClause * get_sortgroupref_clause ( Index  sortref,
List clauses 
)

Definition at line 431 of file tlist.c.

432{
433 ListCell *l;
434
435 foreach(l, clauses)
436 {
438
439 if (cl->tleSortGroupRef == sortref)
440 return cl;
441 }
442
443 elog(ERROR, "ORDER/GROUP BY expression not found in list");
444 return NULL; /* keep compiler quiet */
445}

References elog, ERROR, lfirst, and SortGroupClause::tleSortGroupRef.

Referenced by init_grouping_targets(), and preprocess_groupclause().

◆ get_sortgroupref_clause_noerr()

SortGroupClause * get_sortgroupref_clause_noerr ( Index  sortref,
List clauses 
)

Definition at line 452 of file tlist.c.

453{
454 ListCell *l;
455
456 foreach(l, clauses)
457 {
459
460 if (cl->tleSortGroupRef == sortref)
461 return cl;
462 }
463
464 return NULL;
465}

References lfirst, and SortGroupClause::tleSortGroupRef.

Referenced by find_em_for_rel_target(), foreign_grouping_ok(), group_keys_reorder_by_pathkeys(), make_group_input_target(), and make_partial_grouping_target().

◆ get_sortgroupref_tle()

TargetEntry * get_sortgroupref_tle ( Index  sortref,
List targetList 
)

Definition at line 354 of file tlist.c.

355{
356 ListCell *l;
357
358 foreach(l, targetList)
359 {
360 TargetEntry *tle = (TargetEntry *) lfirst(l);
361
362 if (tle->ressortgroupref == sortref)
363 return tle;
364 }
365
366 elog(ERROR, "ORDER/GROUP BY expression not found in targetlist");
367 return NULL; /* keep compiler quiet */
368}
Index ressortgroupref
Definition: primnodes.h:2245

References elog, ERROR, lfirst, and TargetEntry::ressortgroupref.

Referenced by convert_subquery_pathkeys(), deparseSortGroupClause(), foreign_expr_walker(), get_rule_sortgroupclause(), get_sortgroupclause_tle(), make_unique_from_pathkeys(), prepare_sort_from_pathkeys(), and transformDistinctOnClause().

◆ is_pseudo_constant_for_index()

bool is_pseudo_constant_for_index ( PlannerInfo root,
Node expr,
IndexOptInfo index 
)

Definition at line 4539 of file indxpath.c.

4540{
4541 /* pull_varnos is cheaper than volatility check, so do that first */
4542 if (bms_is_member(index->rel->relid, pull_varnos(root, expr)))
4543 return false; /* no good, contains Var of table */
4545 return false; /* no good, volatile comparison value */
4546 return true;
4547}
Definition: type.h:96
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:114

References bms_is_member(), contain_volatile_functions(), pull_varnos(), and root.

◆ locate_var_of_level()

int locate_var_of_level ( Node node,
int  levelsup 
)

Definition at line 555 of file var.c.

556{
558
559 context.var_location = -1; /* in case we find nothing */
560 context.sublevels_up = levelsup;
561
564 &context,
565 0);
566
567 return context.var_location;
568}
static bool locate_var_of_level_walker(Node *node, locate_var_of_level_context *context)
Definition: var.c:571

References locate_var_of_level_walker(), query_or_expression_tree_walker, locate_var_of_level_context::sublevels_up, and locate_var_of_level_context::var_location.

Referenced by check_agg_arguments(), checkExprIsVarFree(), and transformSetOperationTree().

◆ make_SAOP_expr()

ScalarArrayOpExpr * make_SAOP_expr ( Oid  oper,
Node leftexpr,
Oid  coltype,
Oid  arraycollid,
Oid  inputcollid,
List exprs,
bool  haveNonConst 
)

Definition at line 5835 of file clauses.c.

5837{
5838 Node *arrayNode = NULL;
5839 ScalarArrayOpExpr *saopexpr = NULL;
5840 Oid arraytype = get_array_type(coltype);
5841
5842 if (!OidIsValid(arraytype))
5843 return NULL;
5844
5845 /*
5846 * Assemble an array from the list of constants. It seems more profitable
5847 * to build a const array. But in the presence of other nodes, we don't
5848 * have a specific value here and must employ an ArrayExpr instead.
5849 */
5850 if (haveNonConst)
5851 {
5852 ArrayExpr *arrayExpr = makeNode(ArrayExpr);
5853
5854 /* array_collid will be set by parse_collate.c */
5855 arrayExpr->element_typeid = coltype;
5856 arrayExpr->array_typeid = arraytype;
5857 arrayExpr->multidims = false;
5858 arrayExpr->elements = exprs;
5859 arrayExpr->location = -1;
5860
5861 arrayNode = (Node *) arrayExpr;
5862 }
5863 else
5864 {
5865 int16 typlen;
5866 bool typbyval;
5867 char typalign;
5868 Datum *elems;
5869 bool *nulls;
5870 int i = 0;
5871 ArrayType *arrayConst;
5872 int dims[1] = {list_length(exprs)};
5873 int lbs[1] = {1};
5874
5875 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
5876
5877 elems = palloc_array(Datum, list_length(exprs));
5878 nulls = palloc_array(bool, list_length(exprs));
5879 foreach_node(Const, value, exprs)
5880 {
5881 elems[i] = value->constvalue;
5882 nulls[i++] = value->constisnull;
5883 }
5884
5885 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
5886 coltype, typlen, typbyval, typalign);
5887 arrayNode = (Node *) makeConst(arraytype, -1, arraycollid,
5888 -1, PointerGetDatum(arrayConst),
5889 false, false);
5890
5891 pfree(elems);
5892 pfree(nulls);
5893 list_free(exprs);
5894 }
5895
5896 /* Build the SAOP expression node */
5897 saopexpr = makeNode(ScalarArrayOpExpr);
5898 saopexpr->opno = oper;
5899 saopexpr->opfuncid = get_opcode(oper);
5900 saopexpr->hashfuncid = InvalidOid;
5901 saopexpr->negfuncid = InvalidOid;
5902 saopexpr->useOr = true;
5903 saopexpr->inputcollid = inputcollid;
5904 saopexpr->args = list_make2(leftexpr, arrayNode);
5905 saopexpr->location = -1;
5906
5907 return saopexpr;
5908}
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3495
#define OidIsValid(objectId)
Definition: c.h:794
#define palloc_array(type, count)
Definition: fe_memutils.h:76
static struct @171 value
int i
Definition: isn.c:77
void list_free(List *list)
Definition: list.c:1546
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2421
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1435
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2937
#define makeNode(_type_)
Definition: nodes.h:161
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:371
#define foreach_node(type, var, lst)
Definition: pg_list.h:496
#define list_make2(x1, x2)
Definition: pg_list.h:214
char typalign
Definition: pg_type.h:176
#define InvalidOid
Definition: postgres_ext.h:37
ParseLoc location
Definition: primnodes.h:1421
ParseLoc location
Definition: primnodes.h:951

References ScalarArrayOpExpr::args, construct_md_array(), foreach_node, get_array_type(), get_opcode(), get_typlenbyvalalign(), i, InvalidOid, list_free(), list_length(), list_make2, ScalarArrayOpExpr::location, ArrayExpr::location, makeConst(), makeNode, OidIsValid, oper(), ScalarArrayOpExpr::opno, palloc_array, pfree(), PointerGetDatum(), typalign, ScalarArrayOpExpr::useOr, and value.

Referenced by convert_VALUES_to_ANY(), and match_orclause_to_indexcol().

◆ negate_clause()

Node * negate_clause ( Node node)

Definition at line 73 of file prepqual.c.

74{
75 if (node == NULL) /* should not happen */
76 elog(ERROR, "can't negate an empty subexpression");
77 switch (nodeTag(node))
78 {
79 case T_Const:
80 {
81 Const *c = (Const *) node;
82
83 /* NOT NULL is still NULL */
84 if (c->constisnull)
85 return makeBoolConst(false, true);
86 /* otherwise pretty easy */
87 return makeBoolConst(!DatumGetBool(c->constvalue), false);
88 }
89 break;
90 case T_OpExpr:
91 {
92 /*
93 * Negate operator if possible: (NOT (< A B)) => (>= A B)
94 */
95 OpExpr *opexpr = (OpExpr *) node;
96 Oid negator = get_negator(opexpr->opno);
97
98 if (negator)
99 {
100 OpExpr *newopexpr = makeNode(OpExpr);
101
102 newopexpr->opno = negator;
103 newopexpr->opfuncid = InvalidOid;
104 newopexpr->opresulttype = opexpr->opresulttype;
105 newopexpr->opretset = opexpr->opretset;
106 newopexpr->opcollid = opexpr->opcollid;
107 newopexpr->inputcollid = opexpr->inputcollid;
108 newopexpr->args = opexpr->args;
109 newopexpr->location = opexpr->location;
110 return (Node *) newopexpr;
111 }
112 }
113 break;
114 case T_ScalarArrayOpExpr:
115 {
116 /*
117 * Negate a ScalarArrayOpExpr if its operator has a negator;
118 * for example x = ANY (list) becomes x <> ALL (list)
119 */
120 ScalarArrayOpExpr *saopexpr = (ScalarArrayOpExpr *) node;
121 Oid negator = get_negator(saopexpr->opno);
122
123 if (negator)
124 {
126
127 newopexpr->opno = negator;
128 newopexpr->opfuncid = InvalidOid;
129 newopexpr->hashfuncid = InvalidOid;
130 newopexpr->negfuncid = InvalidOid;
131 newopexpr->useOr = !saopexpr->useOr;
132 newopexpr->inputcollid = saopexpr->inputcollid;
133 newopexpr->args = saopexpr->args;
134 newopexpr->location = saopexpr->location;
135 return (Node *) newopexpr;
136 }
137 }
138 break;
139 case T_BoolExpr:
140 {
141 BoolExpr *expr = (BoolExpr *) node;
142
143 switch (expr->boolop)
144 {
145 /*--------------------
146 * Apply DeMorgan's Laws:
147 * (NOT (AND A B)) => (OR (NOT A) (NOT B))
148 * (NOT (OR A B)) => (AND (NOT A) (NOT B))
149 * i.e., swap AND for OR and negate each subclause.
150 *
151 * If the input is already AND/OR flat and has no NOT
152 * directly above AND or OR, this transformation preserves
153 * those properties. For example, if no direct child of
154 * the given AND clause is an AND or a NOT-above-OR, then
155 * the recursive calls of negate_clause() can't return any
156 * OR clauses. So we needn't call pull_ors() before
157 * building a new OR clause. Similarly for the OR case.
158 *--------------------
159 */
160 case AND_EXPR:
161 {
162 List *nargs = NIL;
163 ListCell *lc;
164
165 foreach(lc, expr->args)
166 {
167 nargs = lappend(nargs,
168 negate_clause(lfirst(lc)));
169 }
170 return (Node *) make_orclause(nargs);
171 }
172 break;
173 case OR_EXPR:
174 {
175 List *nargs = NIL;
176 ListCell *lc;
177
178 foreach(lc, expr->args)
179 {
180 nargs = lappend(nargs,
181 negate_clause(lfirst(lc)));
182 }
183 return (Node *) make_andclause(nargs);
184 }
185 break;
186 case NOT_EXPR:
187
188 /*
189 * NOT underneath NOT: they cancel. We assume the
190 * input is already simplified, so no need to recurse.
191 */
192 return (Node *) linitial(expr->args);
193 default:
194 elog(ERROR, "unrecognized boolop: %d",
195 (int) expr->boolop);
196 break;
197 }
198 }
199 break;
200 case T_NullTest:
201 {
202 NullTest *expr = (NullTest *) node;
203
204 /*
205 * In the rowtype case, the two flavors of NullTest are *not*
206 * logical inverses, so we can't simplify. But it does work
207 * for scalar datatypes.
208 */
209 if (!expr->argisrow)
210 {
211 NullTest *newexpr = makeNode(NullTest);
212
213 newexpr->arg = expr->arg;
214 newexpr->nulltesttype = (expr->nulltesttype == IS_NULL ?
216 newexpr->argisrow = expr->argisrow;
217 newexpr->location = expr->location;
218 return (Node *) newexpr;
219 }
220 }
221 break;
222 case T_BooleanTest:
223 {
224 BooleanTest *expr = (BooleanTest *) node;
225 BooleanTest *newexpr = makeNode(BooleanTest);
226
227 newexpr->arg = expr->arg;
228 switch (expr->booltesttype)
229 {
230 case IS_TRUE:
231 newexpr->booltesttype = IS_NOT_TRUE;
232 break;
233 case IS_NOT_TRUE:
234 newexpr->booltesttype = IS_TRUE;
235 break;
236 case IS_FALSE:
237 newexpr->booltesttype = IS_NOT_FALSE;
238 break;
239 case IS_NOT_FALSE:
240 newexpr->booltesttype = IS_FALSE;
241 break;
242 case IS_UNKNOWN:
243 newexpr->booltesttype = IS_NOT_UNKNOWN;
244 break;
245 case IS_NOT_UNKNOWN:
246 newexpr->booltesttype = IS_UNKNOWN;
247 break;
248 default:
249 elog(ERROR, "unrecognized booltesttype: %d",
250 (int) expr->booltesttype);
251 break;
252 }
253 newexpr->location = expr->location;
254 return (Node *) newexpr;
255 }
256 break;
257 default:
258 /* else fall through */
259 break;
260 }
261
262 /*
263 * Otherwise we don't know how to simplify this, so just tack on an
264 * explicit NOT node.
265 */
266 return (Node *) make_notclause((Expr *) node);
267}
Oid get_negator(Oid opno)
Definition: lsyscache.c:1683
Expr * make_orclause(List *orclauses)
Definition: makefuncs.c:743
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:408
Expr * make_andclause(List *andclauses)
Definition: makefuncs.c:727
Expr * make_notclause(Expr *notclause)
Definition: makefuncs.c:759
Node * negate_clause(Node *node)
Definition: prepqual.c:73
char * c
@ IS_NOT_TRUE
Definition: primnodes.h:2001
@ IS_NOT_FALSE
Definition: primnodes.h:2001
@ IS_NOT_UNKNOWN
Definition: primnodes.h:2001
@ IS_TRUE
Definition: primnodes.h:2001
@ IS_UNKNOWN
Definition: primnodes.h:2001
@ IS_FALSE
Definition: primnodes.h:2001
@ AND_EXPR
Definition: primnodes.h:963
@ OR_EXPR
Definition: primnodes.h:963
@ NOT_EXPR
Definition: primnodes.h:963
@ IS_NOT_NULL
Definition: primnodes.h:1977
BoolExprType boolop
Definition: primnodes.h:971
List * args
Definition: primnodes.h:972
ParseLoc location
Definition: primnodes.h:2009
BoolTestType booltesttype
Definition: primnodes.h:2008
Expr * arg
Definition: primnodes.h:2007
NullTestType nulltesttype
Definition: primnodes.h:1984
ParseLoc location
Definition: primnodes.h:1987
Expr * arg
Definition: primnodes.h:1983
ParseLoc location
Definition: primnodes.h:871

References AND_EXPR, NullTest::arg, BooleanTest::arg, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, BoolExpr::boolop, BooleanTest::booltesttype, DatumGetBool(), elog, ERROR, get_negator(), InvalidOid, IS_FALSE, IS_NOT_FALSE, IS_NOT_NULL, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_NULL, IS_TRUE, IS_UNKNOWN, lappend(), lfirst, linitial, OpExpr::location, ScalarArrayOpExpr::location, NullTest::location, BooleanTest::location, make_andclause(), make_notclause(), make_orclause(), makeBoolConst(), makeNode, negate_clause(), NIL, nodeTag, NOT_EXPR, NullTest::nulltesttype, OpExpr::opno, ScalarArrayOpExpr::opno, OR_EXPR, and ScalarArrayOpExpr::useOr.

Referenced by eval_const_expressions_mutator(), match_boolean_partition_clause(), negate_clause(), and simplify_boolean_equality().

◆ plan_cluster_use_sort()

bool plan_cluster_use_sort ( Oid  tableOid,
Oid  indexOid 
)

Definition at line 6844 of file planner.c.

6845{
6847 Query *query;
6848 PlannerGlobal *glob;
6849 RangeTblEntry *rte;
6850 RelOptInfo *rel;
6851 IndexOptInfo *indexInfo;
6852 QualCost indexExprCost;
6853 Cost comparisonCost;
6854 Path *seqScanPath;
6855 Path seqScanAndSortPath;
6856 IndexPath *indexScanPath;
6857 ListCell *lc;
6858
6859 /* We can short-circuit the cost comparison if indexscans are disabled */
6860 if (!enable_indexscan)
6861 return true; /* use sort */
6862
6863 /* Set up mostly-dummy planner state */
6864 query = makeNode(Query);
6865 query->commandType = CMD_SELECT;
6866
6867 glob = makeNode(PlannerGlobal);
6868
6870 root->parse = query;
6871 root->glob = glob;
6872 root->query_level = 1;
6873 root->planner_cxt = CurrentMemoryContext;
6874 root->wt_param_id = -1;
6875 root->join_domains = list_make1(makeNode(JoinDomain));
6876
6877 /* Build a minimal RTE for the rel */
6878 rte = makeNode(RangeTblEntry);
6879 rte->rtekind = RTE_RELATION;
6880 rte->relid = tableOid;
6881 rte->relkind = RELKIND_RELATION; /* Don't be too picky. */
6882 rte->rellockmode = AccessShareLock;
6883 rte->lateral = false;
6884 rte->inh = false;
6885 rte->inFromCl = true;
6886 query->rtable = list_make1(rte);
6887 addRTEPermissionInfo(&query->rteperminfos, rte);
6888
6889 /* Set up RTE/RelOptInfo arrays */
6891
6892 /* Build RelOptInfo */
6893 rel = build_simple_rel(root, 1, NULL);
6894
6895 /* Locate IndexOptInfo for the target index */
6896 indexInfo = NULL;
6897 foreach(lc, rel->indexlist)
6898 {
6899 indexInfo = lfirst_node(IndexOptInfo, lc);
6900 if (indexInfo->indexoid == indexOid)
6901 break;
6902 }
6903
6904 /*
6905 * It's possible that get_relation_info did not generate an IndexOptInfo
6906 * for the desired index; this could happen if it's not yet reached its
6907 * indcheckxmin usability horizon, or if it's a system index and we're
6908 * ignoring system indexes. In such cases we should tell CLUSTER to not
6909 * trust the index contents but use seqscan-and-sort.
6910 */
6911 if (lc == NULL) /* not in the list? */
6912 return true; /* use sort */
6913
6914 /*
6915 * Rather than doing all the pushups that would be needed to use
6916 * set_baserel_size_estimates, just do a quick hack for rows and width.
6917 */
6918 rel->rows = rel->tuples;
6919 rel->reltarget->width = get_relation_data_width(tableOid, NULL);
6920
6921 root->total_table_pages = rel->pages;
6922
6923 /*
6924 * Determine eval cost of the index expressions, if any. We need to
6925 * charge twice that amount for each tuple comparison that happens during
6926 * the sort, since tuplesort.c will have to re-evaluate the index
6927 * expressions each time. (XXX that's pretty inefficient...)
6928 */
6929 cost_qual_eval(&indexExprCost, indexInfo->indexprs, root);
6930 comparisonCost = 2.0 * (indexExprCost.startup + indexExprCost.per_tuple);
6931
6932 /* Estimate the cost of seq scan + sort */
6933 seqScanPath = create_seqscan_path(root, rel, NULL, 0);
6934 cost_sort(&seqScanAndSortPath, root, NIL,
6935 seqScanPath->disabled_nodes,
6936 seqScanPath->total_cost, rel->tuples, rel->reltarget->width,
6937 comparisonCost, maintenance_work_mem, -1.0);
6938
6939 /* Estimate the cost of index scan */
6940 indexScanPath = create_index_path(root, indexInfo,
6941 NIL, NIL, NIL, NIL,
6942 ForwardScanDirection, false,
6943 NULL, 1.0, false);
6944
6945 return (seqScanAndSortPath.total_cost < indexScanPath->path.total_cost);
6946}
void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, int input_disabled_nodes, Cost input_cost, double tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)
Definition: costsize.c:2134
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
Definition: costsize.c:4782
bool enable_indexscan
Definition: costsize.c:146
int maintenance_work_mem
Definition: globals.c:133
#define AccessShareLock
Definition: lockdefs.h:36
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
double Cost
Definition: nodes.h:261
@ CMD_SELECT
Definition: nodes.h:275
RTEPermissionInfo * addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
IndexPath * create_index_path(PlannerInfo *root, IndexOptInfo *index, List *indexclauses, List *indexorderbys, List *indexorderbycols, List *pathkeys, ScanDirection indexscandir, bool indexonly, Relids required_outer, double loop_count, bool partial_path)
Definition: pathnode.c:1049
Path * create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer, int parallel_workers)
Definition: pathnode.c:983
#define lfirst_node(type, lc)
Definition: pg_list.h:176
#define list_make1(x1)
Definition: pg_list.h:212
int32 get_relation_data_width(Oid relid, int32 *attr_widths)
Definition: plancat.c:1474
void setup_simple_rel_arrays(PlannerInfo *root)
Definition: relnode.c:108
RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
Definition: relnode.c:206
@ ForwardScanDirection
Definition: sdir.h:28
Path path
Definition: pathnodes.h:1957
int disabled_nodes
Definition: pathnodes.h:1908
Cost total_cost
Definition: pathnodes.h:1910
Cost per_tuple
Definition: pathnodes.h:48
Cost startup
Definition: pathnodes.h:47
List * rtable
Definition: parsenodes.h:175
CmdType commandType
Definition: parsenodes.h:121
RTEKind rtekind
Definition: parsenodes.h:1105
struct PathTarget * reltarget
Definition: pathnodes.h:949
BlockNumber pages
Definition: pathnodes.h:999
List * indexlist
Definition: pathnodes.h:995
Cardinality rows
Definition: pathnodes.h:933

References AccessShareLock, addRTEPermissionInfo(), build_simple_rel(), CMD_SELECT, Query::commandType, cost_qual_eval(), cost_sort(), create_index_path(), create_seqscan_path(), CurrentMemoryContext, Path::disabled_nodes, enable_indexscan, ForwardScanDirection, get_relation_data_width(), RelOptInfo::indexlist, IndexOptInfo::indexoid, RangeTblEntry::inh, lfirst_node, list_make1, maintenance_work_mem, makeNode, NIL, RelOptInfo::pages, IndexPath::path, QualCost::per_tuple, RelOptInfo::reltarget, root, RelOptInfo::rows, Query::rtable, RTE_RELATION, RangeTblEntry::rtekind, setup_simple_rel_arrays(), QualCost::startup, Path::total_cost, RelOptInfo::tuples, and PathTarget::width.

Referenced by copy_table_data().

◆ plan_create_index_workers()

int plan_create_index_workers ( Oid  tableOid,
Oid  indexOid 
)

Definition at line 6966 of file planner.c.

6967{
6969 Query *query;
6970 PlannerGlobal *glob;
6971 RangeTblEntry *rte;
6972 Relation heap;
6974 RelOptInfo *rel;
6975 int parallel_workers;
6976 BlockNumber heap_blocks;
6977 double reltuples;
6978 double allvisfrac;
6979
6980 /*
6981 * We don't allow performing parallel operation in standalone backend or
6982 * when parallelism is disabled.
6983 */
6985 return 0;
6986
6987 /* Set up largely-dummy planner state */
6988 query = makeNode(Query);
6989 query->commandType = CMD_SELECT;
6990
6991 glob = makeNode(PlannerGlobal);
6992
6994 root->parse = query;
6995 root->glob = glob;
6996 root->query_level = 1;
6997 root->planner_cxt = CurrentMemoryContext;
6998 root->wt_param_id = -1;
6999 root->join_domains = list_make1(makeNode(JoinDomain));
7000
7001 /*
7002 * Build a minimal RTE.
7003 *
7004 * Mark the RTE with inh = true. This is a kludge to prevent
7005 * get_relation_info() from fetching index info, which is necessary
7006 * because it does not expect that any IndexOptInfo is currently
7007 * undergoing REINDEX.
7008 */
7009 rte = makeNode(RangeTblEntry);
7010 rte->rtekind = RTE_RELATION;
7011 rte->relid = tableOid;
7012 rte->relkind = RELKIND_RELATION; /* Don't be too picky. */
7013 rte->rellockmode = AccessShareLock;
7014 rte->lateral = false;
7015 rte->inh = true;
7016 rte->inFromCl = true;
7017 query->rtable = list_make1(rte);
7018 addRTEPermissionInfo(&query->rteperminfos, rte);
7019
7020 /* Set up RTE/RelOptInfo arrays */
7022
7023 /* Build RelOptInfo */
7024 rel = build_simple_rel(root, 1, NULL);
7025
7026 /* Rels are assumed already locked by the caller */
7027 heap = table_open(tableOid, NoLock);
7028 index = index_open(indexOid, NoLock);
7029
7030 /*
7031 * Determine if it's safe to proceed.
7032 *
7033 * Currently, parallel workers can't access the leader's temporary tables.
7034 * Furthermore, any index predicate or index expressions must be parallel
7035 * safe.
7036 */
7037 if (heap->rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
7040 {
7041 parallel_workers = 0;
7042 goto done;
7043 }
7044
7045 /*
7046 * If parallel_workers storage parameter is set for the table, accept that
7047 * as the number of parallel worker processes to launch (though still cap
7048 * at max_parallel_maintenance_workers). Note that we deliberately do not
7049 * consider any other factor when parallel_workers is set. (e.g., memory
7050 * use by workers.)
7051 */
7052 if (rel->rel_parallel_workers != -1)
7053 {
7054 parallel_workers = Min(rel->rel_parallel_workers,
7056 goto done;
7057 }
7058
7059 /*
7060 * Estimate heap relation size ourselves, since rel->pages cannot be
7061 * trusted (heap RTE was marked as inheritance parent)
7062 */
7063 estimate_rel_size(heap, NULL, &heap_blocks, &reltuples, &allvisfrac);
7064
7065 /*
7066 * Determine number of workers to scan the heap relation using generic
7067 * model
7068 */
7069 parallel_workers = compute_parallel_worker(rel, heap_blocks, -1,
7071
7072 /*
7073 * Cap workers based on available maintenance_work_mem as needed.
7074 *
7075 * Note that each tuplesort participant receives an even share of the
7076 * total maintenance_work_mem budget. Aim to leave participants
7077 * (including the leader as a participant) with no less than 32MB of
7078 * memory. This leaves cases where maintenance_work_mem is set to 64MB
7079 * immediately past the threshold of being capable of launching a single
7080 * parallel worker to sort.
7081 */
7082 while (parallel_workers > 0 &&
7083 maintenance_work_mem / (parallel_workers + 1) < 32 * 1024)
7084 parallel_workers--;
7085
7086done:
7088 table_close(heap, NoLock);
7089
7090 return parallel_workers;
7091}
int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers)
Definition: allpaths.c:4702
uint32 BlockNumber
Definition: block.h:31
#define Min(x, y)
Definition: c.h:1003
bool is_parallel_safe(PlannerInfo *root, Node *node)
Definition: clauses.c:765
int max_parallel_maintenance_workers
Definition: globals.c:134
bool IsUnderPostmaster
Definition: globals.c:120
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:133
#define NoLock
Definition: lockdefs.h:34
void estimate_rel_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Definition: plancat.c:1307
List * RelationGetIndexPredicate(Relation relation)
Definition: relcache.c:5205
List * RelationGetIndexExpressions(Relation relation)
Definition: relcache.c:5092
int rel_parallel_workers
Definition: pathnodes.h:1007
Form_pg_class rd_rel
Definition: rel.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, addRTEPermissionInfo(), build_simple_rel(), CMD_SELECT, Query::commandType, compute_parallel_worker(), CurrentMemoryContext, estimate_rel_size(), index_close(), index_open(), RangeTblEntry::inh, is_parallel_safe(), IsUnderPostmaster, list_make1, maintenance_work_mem, makeNode, max_parallel_maintenance_workers, Min, NoLock, RelationData::rd_rel, RelOptInfo::rel_parallel_workers, RelationGetIndexExpressions(), RelationGetIndexPredicate(), root, Query::rtable, RTE_RELATION, RangeTblEntry::rtekind, setup_simple_rel_arrays(), table_close(), and table_open().

Referenced by index_build().

◆ planner()

PlannedStmt * planner ( Query parse,
const char *  query_string,
int  cursorOptions,
ParamListInfo  boundParams,
ExplainState es 
)

Definition at line 315 of file planner.c.

317{
318 PlannedStmt *result;
319
320 if (planner_hook)
321 result = (*planner_hook) (parse, query_string, cursorOptions,
322 boundParams, es);
323 else
324 result = standard_planner(parse, query_string, cursorOptions,
325 boundParams, es);
326
327 pgstat_report_plan_id(result->planId, false);
328
329 return result;
330}
void pgstat_report_plan_id(int64 plan_id, bool force)
planner_hook_type planner_hook
Definition: planner.c:74
PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition: planner.c:333
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
Definition: regcomp.c:717

References parse(), pgstat_report_plan_id(), PlannedStmt::planId, planner_hook, and standard_planner().

Referenced by pg_plan_query().

◆ predicate_implied_by()

bool predicate_implied_by ( List predicate_list,
List clause_list,
bool  weak 
)

Definition at line 152 of file predtest.c.

154{
155 Node *p,
156 *c;
157
158 if (predicate_list == NIL)
159 return true; /* no predicate: implication is vacuous */
160 if (clause_list == NIL)
161 return false; /* no restriction: implication must fail */
162
163 /*
164 * If either input is a single-element list, replace it with its lone
165 * member; this avoids one useless level of AND-recursion. We only need
166 * to worry about this at top level, since eval_const_expressions should
167 * have gotten rid of any trivial ANDs or ORs below that.
168 */
169 if (list_length(predicate_list) == 1)
170 p = (Node *) linitial(predicate_list);
171 else
172 p = (Node *) predicate_list;
173 if (list_length(clause_list) == 1)
174 c = (Node *) linitial(clause_list);
175 else
176 c = (Node *) clause_list;
177
178 /* And away we go ... */
179 return predicate_implied_by_recurse(c, p, weak);
180}
static bool predicate_implied_by_recurse(Node *clause, Node *predicate, bool weak)
Definition: predtest.c:290

References linitial, list_length(), NIL, and predicate_implied_by_recurse().

Referenced by add_predicate_to_index_quals(), build_paths_for_OR(), check_index_predicates(), choose_bitmap_and(), ConstraintImpliedByRelConstraint(), create_bitmap_scan_plan(), create_bitmap_subplan(), create_indexscan_plan(), infer_arbiter_indexes(), and test_predtest().

◆ predicate_refuted_by()

bool predicate_refuted_by ( List predicate_list,
List clause_list,
bool  weak 
)

Definition at line 222 of file predtest.c.

224{
225 Node *p,
226 *c;
227
228 if (predicate_list == NIL)
229 return false; /* no predicate: no refutation is possible */
230 if (clause_list == NIL)
231 return false; /* no restriction: refutation must fail */
232
233 /*
234 * If either input is a single-element list, replace it with its lone
235 * member; this avoids one useless level of AND-recursion. We only need
236 * to worry about this at top level, since eval_const_expressions should
237 * have gotten rid of any trivial ANDs or ORs below that.
238 */
239 if (list_length(predicate_list) == 1)
240 p = (Node *) linitial(predicate_list);
241 else
242 p = (Node *) predicate_list;
243 if (list_length(clause_list) == 1)
244 c = (Node *) linitial(clause_list);
245 else
246 c = (Node *) clause_list;
247
248 /* And away we go ... */
249 return predicate_refuted_by_recurse(c, p, weak);
250}
static bool predicate_refuted_by_recurse(Node *clause, Node *predicate, bool weak)
Definition: predtest.c:531

References linitial, list_length(), NIL, and predicate_refuted_by_recurse().

Referenced by gen_partprune_steps_internal(), relation_excluded_by_constraints(), and test_predtest().

◆ pull_var_clause()

List * pull_var_clause ( Node node,
int  flags 
)

Definition at line 653 of file var.c.

654{
656
657 /* Assert that caller has not specified inconsistent flags */
664
665 context.varlist = NIL;
666 context.flags = flags;
667
668 pull_var_clause_walker(node, &context);
669 return context.varlist;
670}
#define PVC_RECURSE_AGGREGATES
Definition: optimizer.h:189
#define PVC_RECURSE_PLACEHOLDERS
Definition: optimizer.h:193
#define PVC_RECURSE_WINDOWFUNCS
Definition: optimizer.h:191
#define PVC_INCLUDE_WINDOWFUNCS
Definition: optimizer.h:190
#define PVC_INCLUDE_PLACEHOLDERS
Definition: optimizer.h:192
#define PVC_INCLUDE_AGGREGATES
Definition: optimizer.h:188
static bool pull_var_clause_walker(Node *node, pull_var_clause_context *context)
Definition: var.c:673

References Assert(), pull_var_clause_context::flags, NIL, pull_var_clause_walker(), PVC_INCLUDE_AGGREGATES, PVC_INCLUDE_PLACEHOLDERS, PVC_INCLUDE_WINDOWFUNCS, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_WINDOWFUNCS, and pull_var_clause_context::varlist.

Referenced by add_paths_with_pathkeys_for_rel(), AddRelationNewConstraints(), build_base_rel_tlists(), build_remote_returning(), build_tlist_to_deparse(), create_agg_clause_infos(), CreateTriggerFiringOn(), distribute_qual_to_rels(), estimate_num_groups(), find_computable_ec_member(), find_placeholders_in_expr(), fix_placeholder_input_needed_levels(), foreign_grouping_ok(), generate_base_implied_equalities_no_const(), is_var_in_aggref_only(), make_group_input_target(), make_partial_grouping_target(), make_sort_input_target(), make_window_input_target(), preprocess_targetlist(), process_implied_equality(), qual_is_pushdown_safe(), rebuild_eclass_attr_needed(), rebuild_joinclause_attr_needed(), rebuild_placeholder_attr_needed(), semijoin_target_ok(), and StoreRelCheck().

◆ pull_varattnos()

void pull_varattnos ( Node node,
Index  varno,
Bitmapset **  varattnos 
)

◆ pull_varnos()

Bitmapset * pull_varnos ( PlannerInfo root,
Node node 
)

Definition at line 114 of file var.c.

115{
116 pull_varnos_context context;
117
118 context.varnos = NULL;
119 context.root = root;
120 context.sublevels_up = 0;
121
122 /*
123 * Must be prepared to start with a Query or a bare expression tree; if
124 * it's a Query, we don't want to increment sublevels_up.
125 */
128 &context,
129 0);
130
131 return context.varnos;
132}
PlannerInfo * root
Definition: var.c:36
int sublevels_up
Definition: var.c:37
Relids varnos
Definition: var.c:35
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition: var.c:161

References pull_varnos_walker(), query_or_expression_tree_walker, pull_varnos_context::root, root, pull_varnos_context::sublevels_up, and pull_varnos_context::varnos.

Referenced by compute_semijoin_info(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), cost_incremental_sort(), create_agg_clause_infos(), distribute_qual_to_rels(), examine_variable(), expand_indexqual_rowcompare(), extract_lateral_vars_from_PHVs(), find_placeholder_info(), get_eclass_for_sort_expr(), is_pseudo_constant_for_index(), IsTidEqualAnyClause(), join_is_removable(), make_outerjoininfo(), make_plain_restrictinfo(), match_rowcompare_to_indexcol(), match_saopclause_to_indexcol(), NumRelids(), pg_get_expr_worker(), process_implied_equality(), pullup_replace_vars_callback(), remove_leftjoinrel_from_query(), and subquery_planner().

◆ pull_varnos_of_level()

Bitmapset * pull_varnos_of_level ( PlannerInfo root,
Node node,
int  levelsup 
)

Definition at line 140 of file var.c.

141{
142 pull_varnos_context context;
143
144 context.varnos = NULL;
145 context.root = root;
146 context.sublevels_up = levelsup;
147
148 /*
149 * Must be prepared to start with a Query or a bare expression tree; if
150 * it's a Query, we don't want to increment sublevels_up.
151 */
154 &context,
155 0);
156
157 return context.varnos;
158}

References pull_varnos_walker(), query_or_expression_tree_walker, pull_varnos_context::root, root, pull_varnos_context::sublevels_up, and pull_varnos_context::varnos.

Referenced by add_nullingrels_if_needed(), convert_ANY_sublink_to_join(), is_simple_subquery(), jointree_contains_lateral_outer_refs(), and mark_nullable_by_grouping().

◆ pull_vars_of_level()

List * pull_vars_of_level ( Node node,
int  levelsup 
)

Definition at line 339 of file var.c.

340{
341 pull_vars_context context;
342
343 context.vars = NIL;
344 context.sublevels_up = levelsup;
345
346 /*
347 * Must be prepared to start with a Query or a bare expression tree; if
348 * it's a Query, we don't want to increment sublevels_up.
349 */
352 &context,
353 0);
354
355 return context.vars;
356}
int sublevels_up
Definition: var.c:49
List * vars
Definition: var.c:48
static bool pull_vars_walker(Node *node, pull_vars_context *context)
Definition: var.c:359

References NIL, pull_vars_walker(), query_or_expression_tree_walker, pull_vars_context::sublevels_up, and pull_vars_context::vars.

Referenced by extract_lateral_references(), and extract_lateral_vars_from_PHVs().

◆ var_is_nonnullable()

bool var_is_nonnullable ( PlannerInfo root,
Var var,
bool  use_rel_info 
)

Definition at line 4283 of file clauses.c.

4284{
4285 Bitmapset *notnullattnums = NULL;
4286
4287 Assert(IsA(var, Var));
4288
4289 /* skip upper-level Vars */
4290 if (var->varlevelsup != 0)
4291 return false;
4292
4293 /* could the Var be nulled by any outer joins or grouping sets? */
4294 if (!bms_is_empty(var->varnullingrels))
4295 return false;
4296
4297 /* system columns cannot be NULL */
4298 if (var->varattno < 0)
4299 return true;
4300
4301 /*
4302 * Check if the Var is defined as NOT NULL. We retrieve the column NOT
4303 * NULL constraint information from the corresponding RelOptInfo if it is
4304 * available; otherwise, we search the hash table for this information.
4305 */
4306 if (use_rel_info)
4307 {
4308 RelOptInfo *rel = find_base_rel(root, var->varno);
4309
4310 notnullattnums = rel->notnullattnums;
4311 }
4312 else
4313 {
4315
4316 /*
4317 * We must skip inheritance parent tables, as some child tables may
4318 * have a NOT NULL constraint for a column while others may not. This
4319 * cannot happen with partitioned tables, though.
4320 */
4321 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4322 return false;
4323
4324 notnullattnums = find_relation_notnullatts(root, rte->relid);
4325 }
4326
4327 if (var->varattno > 0 &&
4328 bms_is_member(var->varattno, notnullattnums))
4329 return true;
4330
4331 return false;
4332}
#define bms_is_empty(a)
Definition: bitmapset.h:118
#define planner_rt_fetch(rti, root)
Definition: pathnodes.h:610
Bitmapset * find_relation_notnullatts(PlannerInfo *root, Oid relid)
Definition: plancat.c:774
Bitmapset * notnullattnums
Definition: pathnodes.h:987
AttrNumber varattno
Definition: primnodes.h:274

References Assert(), bms_is_empty, bms_is_member(), find_base_rel(), find_relation_notnullatts(), RangeTblEntry::inh, IsA, RelOptInfo::notnullattnums, planner_rt_fetch, root, Var::varattno, Var::varlevelsup, and Var::varno.

Referenced by expr_is_nonnullable().

Variable Documentation

◆ cpu_index_tuple_cost

PGDLLIMPORT double cpu_index_tuple_cost
extern

Definition at line 133 of file costsize.c.

Referenced by genericcostestimate(), and gincostestimate().

◆ cpu_operator_cost

◆ cpu_tuple_cost

◆ debug_parallel_query

PGDLLIMPORT int debug_parallel_query
extern

Definition at line 69 of file planner.c.

Referenced by ProcessParallelMessage(), query_planner(), and standard_planner().

◆ effective_cache_size

PGDLLIMPORT int effective_cache_size
extern

Definition at line 139 of file costsize.c.

Referenced by gistBuildCallback(), gistInitBuffering(), and index_pages_fetched().

◆ enable_distinct_reordering

PGDLLIMPORT bool enable_distinct_reordering
extern

Definition at line 71 of file planner.c.

Referenced by get_useful_pathkeys_for_distinct().

◆ parallel_leader_participation

PGDLLIMPORT bool parallel_leader_participation
extern

Definition at line 70 of file planner.c.

Referenced by ExecGather(), ExecGatherMerge(), ExecInitGather(), and get_parallel_divisor().

◆ parallel_setup_cost

PGDLLIMPORT double parallel_setup_cost
extern

Definition at line 136 of file costsize.c.

Referenced by cost_gather(), cost_gather_merge(), and standard_planner().

◆ parallel_tuple_cost

PGDLLIMPORT double parallel_tuple_cost
extern

Definition at line 135 of file costsize.c.

Referenced by cost_gather(), cost_gather_merge(), and standard_planner().

◆ random_page_cost

PGDLLIMPORT double random_page_cost
extern

◆ recursive_worktable_factor

PGDLLIMPORT double recursive_worktable_factor
extern

Definition at line 137 of file costsize.c.

Referenced by set_cte_size_estimates().

◆ seq_page_cost