PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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
 

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 }
 
enum  NotNullSource { NOTNULL_SOURCE_RELOPT , NOTNULL_SOURCE_HASHTABLE , NOTNULL_SOURCE_CATALOG }
 

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, NotNullSource source)
 
bool expr_is_nonnullable (PlannerInfo *root, Expr *expr, NotNullSource source)
 
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_join_alias_for_parser (Query *query, Node *node, int sublevels_up)
 
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 197 of file optimizer.h.

◆ PVC_INCLUDE_PLACEHOLDERS

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

Definition at line 201 of file optimizer.h.

◆ PVC_INCLUDE_WINDOWFUNCS

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

Definition at line 199 of file optimizer.h.

◆ PVC_RECURSE_AGGREGATES

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

Definition at line 198 of file optimizer.h.

◆ PVC_RECURSE_PLACEHOLDERS

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

Definition at line 202 of file optimizer.h.

◆ PVC_RECURSE_WINDOWFUNCS

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

Definition at line 200 of file optimizer.h.

Typedef Documentation

◆ ExplainState

Definition at line 27 of file optimizer.h.

◆ HeapTuple

Definition at line 42 of file optimizer.h.

◆ IndexOptInfo

Definition at line 36 of file optimizer.h.

◆ ParamListInfo

Definition at line 41 of file optimizer.h.

◆ PlannedStmt

Definition at line 40 of file optimizer.h.

◆ 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

◆ NotNullSource

Enumerator
NOTNULL_SOURCE_RELOPT 
NOTNULL_SOURCE_HASHTABLE 
NOTNULL_SOURCE_CATALOG 

Definition at line 134 of file optimizer.h.

135{
136 NOTNULL_SOURCE_RELOPT, /* Use RelOptInfo */
137 NOTNULL_SOURCE_HASHTABLE, /* Use Global Hash Table */
138 NOTNULL_SOURCE_CATALOG, /* Use System Catalog */
NotNullSource
Definition optimizer.h:135
@ NOTNULL_SOURCE_HASHTABLE
Definition optimizer.h:137
@ NOTNULL_SOURCE_RELOPT
Definition optimizer.h:136
@ NOTNULL_SOURCE_CATALOG
Definition optimizer.h:138

Function Documentation

◆ canonicalize_qual()

Expr * canonicalize_qual ( Expr qual,
bool  is_check 
)
extern

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 */
310
311 return newqual;
312}
#define Assert(condition)
Definition c.h:1002
#define IsA(nodeptr, _type_)
Definition nodes.h:162
static Expr * find_duplicate_ors(Expr *qual, bool is_check)
Definition prepqual.c:406
static int fb(int x)
Definition pg_list.h:54

References Assert, fb(), 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)
extern

Definition at line 215 of file costsize.c.

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

References fb(), and MAXIMUM_ROWCOUNT.

Referenced by adjust_limit_rows_costs(), adjust_statstuple_for_grouping(), 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)
extern

Definition at line 244 of file costsize.c.

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

References Assert, fb(), 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 
)
extern

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 
)
extern

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,
807 }
808 else if (is_andclause(clause))
809 {
810 /* share code with clauselist_selectivity() */
812 ((BoolExpr *) clause)->args,
813 varRelid,
814 jointype,
815 sjinfo,
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,
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;
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,
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,
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:645
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2660
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
Datum arg
Definition elog.c:1323
#define elog(elevel,...)
Definition elog.h:228
#define DEBUG4
Definition elog.h:28
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:258
@ JOIN_INNER
Definition nodes.h:301
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
Definition plancat.c:2225
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition plancat.c:2264
Selectivity function_selectivity(PlannerInfo *root, Oid funcid, List *args, Oid inputcollid, bool is_join, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition plancat.c:2304
static bool DatumGetBool(Datum X)
Definition postgres.h:100
unsigned int Oid
char * s1
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition relnode.c:544
Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition selfuncs.c:1626
Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition selfuncs.c:1784
Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
Definition selfuncs.c:1587
Selectivity scalararraysel(PlannerInfo *root, ScalarArrayOpExpr *clause, bool is_join_clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition selfuncs.c:1902
Selectivity rowcomparesel(PlannerInfo *root, RowCompareExpr *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Definition selfuncs.c:2320
Definition nodes.h:133
Oid opno
Definition primnodes.h:835
Expr * clause
Definition pathnodes.h:2901
int varno
Definition primnodes.h:270
Index varlevelsup
Definition primnodes.h:295

References arg, bms_is_member(), booltestsel(), boolvarsel(), RestrictInfo::clause, clause_selectivity_ext(), clauselist_selectivity_ext(), clauselist_selectivity_or(), CurrentOfExpr::cvarno, DatumGetBool(), DEBUG4, elog, estimate_expression_value(), fb(), find_base_rel(), function_selectivity(), get_notclausearg(), is_andclause(), is_funcclause(), is_notclause(), is_opclause(), is_orclause(), IsA, JOIN_INNER, join_selectivity(), nulltestsel(), restriction_selectivity(), root, rowcomparesel(), s1, scalararraysel(), treat_as_join_clause(), 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 
)
extern

Definition at line 117 of file clausesel.c.

123{
124 Selectivity s1 = 1.0;
125 RelOptInfo *rel;
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,
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 */
180 continue;
181
182 /* Compute the selectivity of this clause in isolation */
183 s2 = clause_selectivity_ext(root, clause, varRelid, jointype, sjinfo,
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 {
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:2391
bool is_pseudo_constant_clause(Node *clause)
Definition clauses.c:2349
bool is_pseudo_constant_clause_relids(Node *clause, Relids relids)
Definition clauses.c:2369
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:1871
void pfree(void *pointer)
Definition mcxt.c:1619
@ RTE_RELATION
#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:1975
#define DEFAULT_RANGE_INEQ_SEL
Definition selfuncs.h:40
#define DEFAULT_INEQ_SEL
Definition selfuncs.h:37
List * args
Definition primnodes.h:853
Selectivity hibound
Definition clausesel.c:38
List * statlist
Definition pathnodes.h:1093
RTEKind rtekind
Definition pathnodes.h:1073

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

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)
extern

Definition at line 519 of file clauses.c.

520{
521 /* We assume here that expression_planner() won't scribble on its input */
522 expr = expression_planner(expr);
523
524 /* Now we can search for non-immutable functions */
525 return contain_mutable_functions((Node *) expr);
526}
bool contain_mutable_functions(Node *clause)
Definition clauses.c:399
Expr * expression_planner(Expr *expr)
Definition planner.c:7010

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 
)
extern

◆ contain_vars_returning_old_or_new()

bool contain_vars_returning_old_or_new ( Node node)
extern

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(), and fb().

Referenced by make_modifytable().

◆ contain_volatile_functions()

bool contain_volatile_functions ( Node clause)
extern

Definition at line 567 of file clauses.c.

568{
570}
static bool contain_volatile_functions_walker(Node *node, void *context)
Definition clauses.c:579

References contain_volatile_functions_walker(), and fb().

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(), create_agg_clause_infos(), distribute_qual_to_rels(), DomainHasConstraints(), 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(), init_notnull_info(), 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)
extern

Definition at line 688 of file clauses.c.

689{
690 /* We assume here that expression_planner() won't scribble on its input */
691 expr = expression_planner(expr);
692
693 /* Now we can search for volatile functions */
694 return contain_volatile_functions((Node *) expr);
695}
bool contain_volatile_functions(Node *clause)
Definition clauses.c:567

References contain_volatile_functions(), and expression_planner().

◆ contain_volatile_functions_not_nextval()

bool contain_volatile_functions_not_nextval ( Node clause)
extern

Definition at line 702 of file clauses.c.

703{
705}
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition clauses.c:715

References contain_volatile_functions_not_nextval_walker(), and fb().

Referenced by BeginCopyFrom().

◆ convert_saop_to_hashed_saop()

void convert_saop_to_hashed_saop ( Node node)
extern

Definition at line 2549 of file clauses.c.

2550{
2552}
static bool convert_saop_to_hashed_saop_walker(Node *node, void *context)
Definition clauses.c:2555

References convert_saop_to_hashed_saop_walker(), and fb().

Referenced by preprocess_expression().

◆ count_nonjunk_tlist_entries()

int count_nonjunk_tlist_entries ( List tlist)
extern

Definition at line 195 of file tlist.c.

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

References fb(), 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 
)
extern

Definition at line 2660 of file clauses.c.

2661{
2663
2664 context.boundParams = root->glob->boundParams; /* bound Params */
2665 /* we do not need to mark the plan as depending on inlined functions */
2666 context.root = NULL;
2667 context.active_fns = NIL; /* nothing being recursively simplified */
2668 context.case_val = NULL; /* no CASE being examined */
2669 context.estimate = true; /* unsafe transformations OK */
2670 return eval_const_expressions_mutator(node, &context);
2671}
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition clauses.c:2705

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(), fb(), 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 
)
extern

Definition at line 2516 of file clauses.c.

2517{
2519
2520 if (root)
2521 context.boundParams = root->glob->boundParams; /* bound Params */
2522 else
2523 context.boundParams = NULL;
2524 context.root = root; /* for inlined-function dependencies */
2525 context.active_fns = NIL; /* nothing being recursively simplified */
2526 context.case_val = NULL; /* no CASE being examined */
2527 context.estimate = false; /* safe transformations only */
2528 return eval_const_expressions_mutator(node, &context);
2529}

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(), fb(), NIL, eval_const_expressions_context::root, and root.

Referenced by apply_child_basequals(), ATExecAttachPartition(), ConstraintImpliedByRelConstraint(), convert_EXISTS_to_ANY(), convert_VALUES_to_ANY(), DoCopy(), expand_insert_targetlist(), expression_planner(), expression_planner_with_deps(), extended_statistics_update(), fetch_statentries_for_relation(), get_proposed_default_constraint(), get_relation_constraints(), get_relation_info(), get_relation_statistics(), infer_arbiter_indexes(), preprocess_expression(), preprocess_function_rtes(), process_implied_equality(), RelationBuildPartitionKey(), RelationGetIndexExpressions(), RelationGetIndexPredicate(), simplify_EXISTS_query(), and SplitPartitionMoveRows().

◆ evaluate_expr()

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

Definition at line 5743 of file clauses.c.

5745{
5746 EState *estate;
5747 ExprState *exprstate;
5748 MemoryContext oldcontext;
5750 bool const_is_null;
5752 bool resultTypByVal;
5753
5754 /*
5755 * To use the executor, we need an EState.
5756 */
5757 estate = CreateExecutorState();
5758
5759 /* We can use the estate's working context to avoid memory leaks. */
5760 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5761
5762 /* Make sure any opfuncids are filled in. */
5763 fix_opfuncids((Node *) expr);
5764
5765 /*
5766 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5767 * because it'd result in recursively invoking eval_const_expressions.)
5768 */
5769 exprstate = ExecInitExpr(expr, NULL);
5770
5771 /*
5772 * And evaluate it.
5773 *
5774 * It is OK to use a default econtext because none of the ExecEvalExpr()
5775 * code used in this situation will use econtext. That might seem
5776 * fortuitous, but it's not so unreasonable --- a constant expression does
5777 * not depend on context, by definition, n'est ce pas?
5778 */
5780 GetPerTupleExprContext(estate),
5781 &const_is_null);
5782
5783 /* Get info needed about result datatype */
5785
5786 /* Get back to outer memory context */
5787 MemoryContextSwitchTo(oldcontext);
5788
5789 /*
5790 * Must copy result out of sub-context used by expression eval.
5791 *
5792 * Also, if it's varlena, forcibly detoast it. This protects us against
5793 * storing TOAST pointers into plans that might outlive the referenced
5794 * data. (makeConst would handle detoasting anyway, but it's worth a few
5795 * extra lines here so that we can do the copy and detoast in one step.)
5796 */
5797 if (!const_is_null)
5798 {
5799 if (resultTypLen == -1)
5801 else
5803 }
5804
5805 /* Release all the junk we just created */
5806 FreeExecutorState(estate);
5807
5808 /*
5809 * Make the constant result node.
5810 */
5811 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5815}
int16_t int16
Definition c.h:678
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:197
EState * CreateExecutorState(void)
Definition execUtils.c:90
#define GetPerTupleExprContext(estate)
Definition executor.h:665
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:444
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition lsyscache.c:2565
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:1859
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
uint64_t Datum
Definition postgres.h:70
#define PointerGetDatum(X)
Definition postgres.h:354
MemoryContext es_query_cxt
Definition execnodes.h:747

References CreateExecutorState(), datumCopy(), EState::es_query_cxt, ExecEvalExprSwitchContext(), ExecInitExpr(), fb(), 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 
)
extern

Definition at line 4946 of file clauses.c.

4948{
4950 Oid *proargtypes = funcform->proargtypes.values;
4951 int pronargs = funcform->pronargs;
4952 bool has_named_args = false;
4953 ListCell *lc;
4954
4955 /*
4956 * If we are asked to match to OUT arguments, then use the proallargtypes
4957 * array (which includes those); otherwise use proargtypes (which
4958 * doesn't). Of course, if proallargtypes is null, we always use
4959 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4960 * considering that we may have nothing to do here, but fortunately the
4961 * common case is include_out_arguments == false.)
4962 */
4964 {
4966 bool isNull;
4967
4970 &isNull);
4971 if (!isNull)
4972 {
4974
4975 pronargs = ARR_DIMS(arr)[0];
4976 if (ARR_NDIM(arr) != 1 ||
4977 pronargs < 0 ||
4978 ARR_HASNULL(arr) ||
4979 ARR_ELEMTYPE(arr) != OIDOID)
4980 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4981 Assert(pronargs >= funcform->pronargs);
4982 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4983 }
4984 }
4985
4986 /* Do we have any named arguments? */
4987 foreach(lc, args)
4988 {
4989 Node *arg = (Node *) lfirst(lc);
4990
4991 if (IsA(arg, NamedArgExpr))
4992 {
4993 has_named_args = true;
4994 break;
4995 }
4996 }
4997
4998 /* If so, we must apply reorder_function_arguments */
4999 if (has_named_args)
5000 {
5002 /* Recheck argument types and add casts if needed */
5003 recheck_cast_function_args(args, result_type,
5005 func_tuple);
5006 }
5007 else if (list_length(args) < pronargs)
5008 {
5009 /* No named args, but we seem to be short some defaults */
5011 /* Recheck argument types and add casts if needed */
5012 recheck_cast_function_args(args, result_type,
5014 func_tuple);
5015 }
5016
5017 return args;
5018}
#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:5097
static List * reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5027
static void recheck_cast_function_args(List *args, Oid result_type, Oid *proargtypes, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5151
#define ERROR
Definition elog.h:40
static void * GETSTRUCT(const HeapTupleData *tuple)
int16 pronargs
Definition pg_proc.h:83
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596

References add_function_defaults(), arg, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, DatumGetArrayTypeP, elog, ERROR, fb(), Form_pg_proc, 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,
NotNullSource  source 
)
extern

Definition at line 4804 of file clauses.c.

4805{
4806 /* since this function recurses, it could be driven to stack overflow */
4808
4809 switch (nodeTag(expr))
4810 {
4811 case T_Var:
4812 {
4813 if (root)
4814 return var_is_nonnullable(root, (Var *) expr, source);
4815 }
4816 break;
4817 case T_Const:
4818 return !((Const *) expr)->constisnull;
4819 case T_CoalesceExpr:
4820 {
4821 /*
4822 * A CoalesceExpr returns NULL if and only if all its
4823 * arguments are NULL. Therefore, we can determine that a
4824 * CoalesceExpr cannot be NULL if at least one of its
4825 * arguments can be proven non-nullable.
4826 */
4828
4830 {
4832 return true;
4833 }
4834 }
4835 break;
4836 case T_MinMaxExpr:
4837 {
4838 /*
4839 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4840 * its arguments evaluate to NULL.
4841 */
4842 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4843
4845 {
4847 return true;
4848 }
4849 }
4850 break;
4851 case T_CaseExpr:
4852 {
4853 /*
4854 * A CASE expression is non-nullable if all branch results are
4855 * non-nullable. We must also verify that the default result
4856 * (ELSE) exists and is non-nullable.
4857 */
4858 CaseExpr *caseexpr = (CaseExpr *) expr;
4859
4860 /* The default result must be present and non-nullable */
4861 if (caseexpr->defresult == NULL ||
4862 !expr_is_nonnullable(root, caseexpr->defresult, source))
4863 return false;
4864
4865 /* All branch results must be non-nullable */
4867 {
4868 if (!expr_is_nonnullable(root, casewhen->result, source))
4869 return false;
4870 }
4871
4872 return true;
4873 }
4874 break;
4875 case T_ArrayExpr:
4876 {
4877 /*
4878 * An ARRAY[] expression always returns a valid Array object,
4879 * even if it is empty (ARRAY[]) or contains NULLs
4880 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4881 */
4882 return true;
4883 }
4884 case T_NullTest:
4885 {
4886 /*
4887 * An IS NULL / IS NOT NULL expression always returns a
4888 * boolean value. It never returns SQL NULL.
4889 */
4890 return true;
4891 }
4892 case T_BooleanTest:
4893 {
4894 /*
4895 * A BooleanTest expression always evaluates to a boolean
4896 * value. It never returns SQL NULL.
4897 */
4898 return true;
4899 }
4900 case T_DistinctExpr:
4901 {
4902 /*
4903 * IS DISTINCT FROM never returns NULL, effectively acting as
4904 * though NULL were a normal data value.
4905 */
4906 return true;
4907 }
4908 case T_RelabelType:
4909 {
4910 /*
4911 * RelabelType does not change the nullability of the data.
4912 * The result is non-nullable if and only if the argument is
4913 * non-nullable.
4914 */
4915 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4916 source);
4917 }
4918 default:
4919 break;
4920 }
4921
4922 return false;
4923}
bool expr_is_nonnullable(PlannerInfo *root, Expr *expr, NotNullSource source)
Definition clauses.c:4804
bool var_is_nonnullable(PlannerInfo *root, Var *var, NotNullSource source)
Definition clauses.c:4660
#define nodeTag(nodeptr)
Definition nodes.h:137
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
static rewind_source * source
Definition pg_rewind.c:89
void check_stack_depth(void)
Definition stack_depth.c:96

References arg, check_stack_depth(), expr_is_nonnullable(), fb(), foreach_ptr, nodeTag, root, source, and var_is_nonnullable().

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

◆ expression_planner()

Expr * expression_planner ( Expr expr)
extern

Definition at line 7010 of file planner.c.

7011{
7012 Node *result;
7013
7014 /*
7015 * Convert named-argument function calls, insert default arguments and
7016 * simplify constant subexprs
7017 */
7019
7020 /* Fill in opfuncid values if missing */
7022
7023 return (Expr *) result;
7024}
uint32 result
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2516

References eval_const_expressions(), fb(), fix_opfuncids(), and result.

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 
)
extern

Definition at line 7037 of file planner.c.

7040{
7041 Node *result;
7042 PlannerGlobal glob;
7044
7045 /* Make up dummy planner state so we can use setrefs machinery */
7046 MemSet(&glob, 0, sizeof(glob));
7047 glob.type = T_PlannerGlobal;
7048 glob.relationOids = NIL;
7049 glob.invalItems = NIL;
7050
7051 MemSet(&root, 0, sizeof(root));
7052 root.type = T_PlannerInfo;
7053 root.glob = &glob;
7054
7055 /*
7056 * Convert named-argument function calls, insert default arguments and
7057 * simplify constant subexprs. Collect identities of inlined functions
7058 * and elided domains, too.
7059 */
7060 result = eval_const_expressions(&root, (Node *) expr);
7061
7062 /* Fill in opfuncid values if missing */
7064
7065 /*
7066 * Now walk the finished expression to find anything else we ought to
7067 * record as an expression dependency.
7068 */
7070
7071 *relationOids = glob.relationOids;
7072 *invalItems = glob.invalItems;
7073
7074 return (Expr *) result;
7075}
#define MemSet(start, val, len)
Definition c.h:1147
bool extract_query_dependencies_walker(Node *node, PlannerInfo *context)
Definition setrefs.c:3716
List * invalItems
Definition pathnodes.h:230
List * relationOids
Definition pathnodes.h:227

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

Referenced by GetCachedExpression().

◆ extract_query_dependencies()

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

Definition at line 3680 of file setrefs.c.

3684{
3685 PlannerGlobal glob;
3687
3688 /* Make up dummy planner state so we can use this module's machinery */
3689 MemSet(&glob, 0, sizeof(glob));
3690 glob.type = T_PlannerGlobal;
3691 glob.relationOids = NIL;
3692 glob.invalItems = NIL;
3693 /* Hack: we use glob.dependsOnRole to collect hasRowSecurity flags */
3694 glob.dependsOnRole = false;
3695
3696 MemSet(&root, 0, sizeof(root));
3697 root.type = T_PlannerInfo;
3698 root.glob = &glob;
3699
3701
3702 *relationOids = glob.relationOids;
3703 *invalItems = glob.invalItems;
3704 *hasRowSecurity = glob.dependsOnRole;
3705}
bool dependsOnRole
Definition pathnodes.h:251

References PlannerGlobal::dependsOnRole, extract_query_dependencies_walker(), fb(), 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 
)
extern

Definition at line 999 of file var.c.

1000{
1002
1003 /*
1004 * We do not expect this to be applied to the whole Query, only to
1005 * expressions or LATERAL subqueries. Hence, if the top node is a Query,
1006 * it's okay to immediately increment sublevels_up.
1007 */
1008 Assert(node != (Node *) query);
1009
1010 context.root = root;
1011 context.query = query;
1012 context.sublevels_up = 0;
1013 /* flag whether grouping expressions could possibly contain SubLinks */
1014 context.possible_sublink = query->hasSubLinks;
1015 /* if hasSubLinks is already true, no need to work hard */
1016 context.inserted_sublink = query->hasSubLinks;
1017
1018 return flatten_group_exprs_mutator(node, &context);
1019}
static Node * flatten_group_exprs_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition var.c:1022

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 check_output_expressions(), get_query_def(), query_outputs_are_not_nullable(), and subquery_planner().

◆ flatten_join_alias_for_parser()

Node * flatten_join_alias_for_parser ( Query query,
Node node,
int  sublevels_up 
)
extern

Definition at line 819 of file var.c.

820{
822
823 /*
824 * We do not expect this to be applied to the whole Query, only to
825 * expressions or LATERAL subqueries. Hence, if the top node is a Query,
826 * it's okay to immediately increment sublevels_up.
827 */
828 Assert(node != (Node *) query);
829
830 context.root = NULL;
831 context.query = query;
832 context.sublevels_up = sublevels_up;
833 /* flag whether join aliases could possibly contain SubLinks */
834 context.possible_sublink = query->hasSubLinks;
835 /* if hasSubLinks is already true, no need to work hard */
836 context.inserted_sublink = query->hasSubLinks;
837
838 return flatten_join_alias_vars_mutator(node, &context);
839}
static Node * flatten_join_alias_vars_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition var.c:842

References Assert, fb(), 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, and flatten_join_alias_vars_context::sublevels_up.

Referenced by finalize_grouping_exprs_walker(), and parseCheckAggregates().

◆ flatten_join_alias_vars()

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

Definition at line 781 of file var.c.

782{
784
785 /*
786 * We do not expect this to be applied to the whole Query, only to
787 * expressions or LATERAL subqueries. Hence, if the top node is a Query,
788 * it's okay to immediately increment sublevels_up.
789 */
790 Assert(node != (Node *) query);
791
792 context.root = root;
793 context.query = query;
794 context.sublevels_up = 0;
795 /* flag whether join aliases could possibly contain SubLinks */
796 context.possible_sublink = query->hasSubLinks;
797 /* if hasSubLinks is already true, no need to work hard */
798 context.inserted_sublink = query->hasSubLinks;
799
800 return flatten_join_alias_vars_mutator(node, &context);
801}

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 preprocess_expression(), pull_up_simple_subquery(), query_outputs_are_not_nullable(), sublink_testexpr_is_not_nullable(), and subquery_planner().

◆ get_sortgroupclause_expr()

Node * get_sortgroupclause_expr ( SortGroupClause sgClause,
List targetList 
)
extern

Definition at line 388 of file tlist.c.

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

References fb(), 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 
)
extern

Definition at line 401 of file tlist.c.

402{
403 List *result = NIL;
404 ListCell *l;
405
406 foreach(l, sgClauses)
407 {
409 Node *sortexpr;
410
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 fb(), get_sortgroupclause_expr(), lappend(), lfirst, NIL, and result.

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 
)
extern

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, fb(), and lfirst.

Referenced by init_grouping_targets(), and preprocess_groupclause().

◆ get_sortgroupref_clause_noerr()

SortGroupClause * get_sortgroupref_clause_noerr ( Index  sortref,
List clauses 
)
extern

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 fb(), and lfirst.

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 
)
extern

Definition at line 354 of file tlist.c.

355{
356 ListCell *l;
357
358 foreach(l, targetList)
359 {
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}

References elog, ERROR, fb(), and lfirst.

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 
)
extern

Definition at line 4453 of file indxpath.c.

4454{
4455 /* pull_varnos is cheaper than volatility check, so do that first */
4456 if (bms_is_member(index->rel->relid, pull_varnos(root, expr)))
4457 return false; /* no good, contains Var of table */
4459 return false; /* no good, volatile comparison value */
4460 return true;
4461}
Definition type.h:97
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 
)
extern

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 fb(), 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 
)
extern

Definition at line 6543 of file clauses.c.

6545{
6546 Node *arrayNode = NULL;
6548 Oid arraytype = get_array_type(coltype);
6549
6550 if (!OidIsValid(arraytype))
6551 return NULL;
6552
6553 /*
6554 * Assemble an array from the list of constants. It seems more profitable
6555 * to build a const array. But in the presence of other nodes, we don't
6556 * have a specific value here and must employ an ArrayExpr instead.
6557 */
6558 if (haveNonConst)
6559 {
6561
6562 /* array_collid will be set by parse_collate.c */
6563 arrayExpr->element_typeid = coltype;
6564 arrayExpr->array_typeid = arraytype;
6565 arrayExpr->multidims = false;
6566 arrayExpr->elements = exprs;
6567 arrayExpr->location = -1;
6568
6569 arrayNode = (Node *) arrayExpr;
6570 }
6571 else
6572 {
6573 int16 typlen;
6574 bool typbyval;
6575 char typalign;
6576 Datum *elems;
6577 bool *nulls;
6578 int i = 0;
6580 int dims[1] = {list_length(exprs)};
6581 int lbs[1] = {1};
6582
6583 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
6584
6585 elems = palloc_array(Datum, list_length(exprs));
6586 nulls = palloc_array(bool, list_length(exprs));
6587 foreach_node(Const, value, exprs)
6588 {
6589 elems[i] = value->constvalue;
6590 nulls[i++] = value->constisnull;
6591 }
6592
6593 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
6594 coltype, typlen, typbyval, typalign);
6597 false, false);
6598
6599 pfree(elems);
6600 pfree(nulls);
6601 list_free(exprs);
6602 }
6603
6604 /* Build the SAOP expression node */
6606 saopexpr->opno = oper;
6607 saopexpr->opfuncid = get_opcode(oper);
6608 saopexpr->hashfuncid = InvalidOid;
6609 saopexpr->negfuncid = InvalidOid;
6610 saopexpr->useOr = true;
6611 saopexpr->inputcollid = inputcollid;
6613 saopexpr->location = -1;
6614
6615 return saopexpr;
6616}
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
#define OidIsValid(objectId)
Definition c.h:917
#define palloc_array(type, count)
Definition fe_memutils.h:91
static struct @175 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:2585
RegProcedure get_opcode(Oid opno)
Definition lsyscache.c:1585
Oid get_array_type(Oid typid)
Definition lsyscache.c:3103
#define makeNode(_type_)
Definition nodes.h:159
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition parse_oper.c:376
#define foreach_node(type, var, lst)
Definition pg_list.h:528
#define list_make2(x1, x2)
Definition pg_list.h:246
char typalign
Definition pg_type.h:178
#define InvalidOid

References construct_md_array(), fb(), foreach_node, get_array_type(), get_opcode(), get_typlenbyvalalign(), i, InvalidOid, list_free(), list_length(), list_make2, makeConst(), makeNode, OidIsValid, oper(), palloc_array, pfree(), PointerGetDatum, typalign, and value.

Referenced by convert_VALUES_to_ANY(), and match_orclause_to_indexcol().

◆ negate_clause()

Node * negate_clause ( Node node)
extern

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 {
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;
115 {
116 /*
117 * Negate a ScalarArrayOpExpr if its operator has a negator;
118 * for example x = ANY (list) becomes x <> ALL (list)
119 */
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,
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,
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 {
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;
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:1847
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:1999
@ IS_NOT_FALSE
Definition primnodes.h:1999
@ IS_NOT_UNKNOWN
Definition primnodes.h:1999
@ IS_TRUE
Definition primnodes.h:1999
@ IS_UNKNOWN
Definition primnodes.h:1999
@ IS_FALSE
Definition primnodes.h:1999
@ AND_EXPR
Definition primnodes.h:945
@ OR_EXPR
Definition primnodes.h:945
@ NOT_EXPR
Definition primnodes.h:945
@ IS_NOT_NULL
Definition primnodes.h:1975
BoolExprType boolop
Definition primnodes.h:953
List * args
Definition primnodes.h:954
ParseLoc location
Definition primnodes.h:2007
BoolTestType booltesttype
Definition primnodes.h:2006
NullTestType nulltesttype
Definition primnodes.h:1982
ParseLoc location
Definition primnodes.h:1985
Expr * arg
Definition primnodes.h:1981
ParseLoc location
Definition primnodes.h:856

References AND_EXPR, NullTest::arg, BooleanTest::arg, OpExpr::args, BoolExpr::args, BoolExpr::boolop, BooleanTest::booltesttype, DatumGetBool(), elog, ERROR, fb(), 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, NullTest::location, BooleanTest::location, make_andclause(), make_notclause(), make_orclause(), makeBoolConst(), makeNode, negate_clause(), NIL, nodeTag, NOT_EXPR, NullTest::nulltesttype, OpExpr::opno, and OR_EXPR.

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 
)
extern

Definition at line 7090 of file planner.c.

7091{
7093 Query *query;
7094 PlannerGlobal *glob;
7096 RelOptInfo *rel;
7097 IndexOptInfo *indexInfo;
7103 ListCell *lc;
7104
7105 /* We can short-circuit the cost comparison if indexscans are disabled */
7106 if (!enable_indexscan)
7107 return true; /* use sort */
7108
7109 /* Set up mostly-dummy planner state */
7110 query = makeNode(Query);
7111 query->commandType = CMD_SELECT;
7112
7113 glob = makeNode(PlannerGlobal);
7114
7116 root->parse = query;
7117 root->glob = glob;
7118 root->query_level = 1;
7119 root->planner_cxt = CurrentMemoryContext;
7120 root->wt_param_id = -1;
7121 root->join_domains = list_make1(makeNode(JoinDomain));
7122
7123 /* Build a minimal RTE for the rel */
7125 rte->rtekind = RTE_RELATION;
7126 rte->relid = tableOid;
7127 rte->relkind = RELKIND_RELATION; /* Don't be too picky. */
7128 rte->rellockmode = AccessShareLock;
7129 rte->lateral = false;
7130 rte->inh = false;
7131 rte->inFromCl = true;
7132 query->rtable = list_make1(rte);
7133 addRTEPermissionInfo(&query->rteperminfos, rte);
7134
7135 /* Set up RTE/RelOptInfo arrays */
7137
7138 /* Build RelOptInfo */
7139 rel = build_simple_rel(root, 1, NULL);
7140
7141 /* Locate IndexOptInfo for the target index */
7142 indexInfo = NULL;
7143 foreach(lc, rel->indexlist)
7144 {
7145 indexInfo = lfirst_node(IndexOptInfo, lc);
7146 if (indexInfo->indexoid == indexOid)
7147 break;
7148 }
7149
7150 /*
7151 * It's possible that get_relation_info did not generate an IndexOptInfo
7152 * for the desired index; this could happen if it's not yet reached its
7153 * indcheckxmin usability horizon, or if it's a system index and we're
7154 * ignoring system indexes. In such cases we should tell CLUSTER to not
7155 * trust the index contents but use seqscan-and-sort.
7156 */
7157 if (lc == NULL) /* not in the list? */
7158 return true; /* use sort */
7159
7160 /*
7161 * Rather than doing all the pushups that would be needed to use
7162 * set_baserel_size_estimates, just do a quick hack for rows and width.
7163 */
7164 rel->rows = rel->tuples;
7165 rel->reltarget->width = get_relation_data_width(tableOid, NULL);
7166
7167 root->total_table_pages = rel->pages;
7168
7169 /*
7170 * Determine eval cost of the index expressions, if any. We need to
7171 * charge twice that amount for each tuple comparison that happens during
7172 * the sort, since tuplesort.c will have to re-evaluate the index
7173 * expressions each time. (XXX that's pretty inefficient...)
7174 */
7175 cost_qual_eval(&indexExprCost, indexInfo->indexprs, root);
7176 comparisonCost = 2.0 * (indexExprCost.startup + indexExprCost.per_tuple);
7177
7178 /* Estimate the cost of seq scan + sort */
7181 seqScanPath->disabled_nodes,
7182 seqScanPath->total_cost, rel->tuples, rel->reltarget->width,
7184
7185 /* Estimate the cost of index scan */
7187 NIL, NIL, NIL, NIL,
7188 ForwardScanDirection, false,
7189 NULL, 1.0, false);
7190
7191 return (seqScanAndSortPath.total_cost < indexScanPath->path.total_cost);
7192}
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:2202
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
Definition costsize.c:4923
bool enable_indexscan
Definition costsize.c:147
int maintenance_work_mem
Definition globals.c:135
#define AccessShareLock
Definition lockdefs.h:36
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
double Cost
Definition nodes.h:259
@ CMD_SELECT
Definition nodes.h:273
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:1092
Path * create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer, int parallel_workers)
Definition pathnode.c:1026
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define list_make1(x1)
Definition pg_list.h:244
int32 get_relation_data_width(Oid relid, int32 *attr_widths)
Definition plancat.c:1472
void setup_simple_rel_arrays(PlannerInfo *root)
Definition relnode.c:114
RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
Definition relnode.c:212
@ ForwardScanDirection
Definition sdir.h:28
List * rtable
Definition parsenodes.h:180
CmdType commandType
Definition parsenodes.h:124
struct PathTarget * reltarget
Definition pathnodes.h:1045
Cardinality tuples
Definition pathnodes.h:1096
BlockNumber pages
Definition pathnodes.h:1095
List * indexlist
Definition pathnodes.h:1091
Cardinality rows
Definition pathnodes.h:1027

References AccessShareLock, addRTEPermissionInfo(), build_simple_rel(), CMD_SELECT, Query::commandType, cost_qual_eval(), cost_sort(), create_index_path(), create_seqscan_path(), CurrentMemoryContext, enable_indexscan, fb(), ForwardScanDirection, get_relation_data_width(), RelOptInfo::indexlist, IndexOptInfo::indexoid, lfirst_node, list_make1, maintenance_work_mem, makeNode, NIL, RelOptInfo::pages, RelOptInfo::reltarget, root, RelOptInfo::rows, Query::rtable, RTE_RELATION, setup_simple_rel_arrays(), RelOptInfo::tuples, and PathTarget::width.

Referenced by copy_table_data().

◆ plan_create_index_workers()

int plan_create_index_workers ( Oid  tableOid,
Oid  indexOid 
)
extern

Definition at line 7212 of file planner.c.

7213{
7215 Query *query;
7216 PlannerGlobal *glob;
7218 Relation heap;
7220 RelOptInfo *rel;
7221 int parallel_workers;
7223 double reltuples;
7224 double allvisfrac;
7225
7226 /*
7227 * We don't allow performing parallel operation in standalone backend or
7228 * when parallelism is disabled.
7229 */
7231 return 0;
7232
7233 /* Set up largely-dummy planner state */
7234 query = makeNode(Query);
7235 query->commandType = CMD_SELECT;
7236
7237 glob = makeNode(PlannerGlobal);
7238
7240 root->parse = query;
7241 root->glob = glob;
7242 root->query_level = 1;
7243 root->planner_cxt = CurrentMemoryContext;
7244 root->wt_param_id = -1;
7245 root->join_domains = list_make1(makeNode(JoinDomain));
7246
7247 /*
7248 * Build a minimal RTE.
7249 *
7250 * Mark the RTE with inh = true. This is a kludge to prevent
7251 * get_relation_info() from fetching index info, which is necessary
7252 * because it does not expect that any IndexOptInfo is currently
7253 * undergoing REINDEX.
7254 */
7256 rte->rtekind = RTE_RELATION;
7257 rte->relid = tableOid;
7258 rte->relkind = RELKIND_RELATION; /* Don't be too picky. */
7259 rte->rellockmode = AccessShareLock;
7260 rte->lateral = false;
7261 rte->inh = true;
7262 rte->inFromCl = true;
7263 query->rtable = list_make1(rte);
7264 addRTEPermissionInfo(&query->rteperminfos, rte);
7265
7266 /* Set up RTE/RelOptInfo arrays */
7268
7269 /* Build RelOptInfo */
7270 rel = build_simple_rel(root, 1, NULL);
7271
7272 /* Rels are assumed already locked by the caller */
7273 heap = table_open(tableOid, NoLock);
7274 index = index_open(indexOid, NoLock);
7275
7276 /*
7277 * Determine if it's safe to proceed.
7278 *
7279 * Currently, parallel workers can't access the leader's temporary tables.
7280 * Furthermore, any index predicate or index expressions must be parallel
7281 * safe.
7282 */
7283 if (heap->rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
7286 {
7287 parallel_workers = 0;
7288 goto done;
7289 }
7290
7291 /*
7292 * If parallel_workers storage parameter is set for the table, accept that
7293 * as the number of parallel worker processes to launch (though still cap
7294 * at max_parallel_maintenance_workers). Note that we deliberately do not
7295 * consider any other factor when parallel_workers is set. (e.g., memory
7296 * use by workers.)
7297 */
7298 if (rel->rel_parallel_workers != -1)
7299 {
7300 parallel_workers = Min(rel->rel_parallel_workers,
7302 goto done;
7303 }
7304
7305 /*
7306 * Estimate heap relation size ourselves, since rel->pages cannot be
7307 * trusted (heap RTE was marked as inheritance parent)
7308 */
7309 estimate_rel_size(heap, NULL, &heap_blocks, &reltuples, &allvisfrac);
7310
7311 /*
7312 * Determine number of workers to scan the heap relation using generic
7313 * model
7314 */
7315 parallel_workers = compute_parallel_worker(rel, heap_blocks, -1,
7317
7318 /*
7319 * Cap workers based on available maintenance_work_mem as needed.
7320 *
7321 * Note that each tuplesort participant receives an even share of the
7322 * total maintenance_work_mem budget. Aim to leave participants
7323 * (including the leader as a participant) with no less than 32MB of
7324 * memory. This leaves cases where maintenance_work_mem is set to 64MB
7325 * immediately past the threshold of being capable of launching a single
7326 * parallel worker to sort.
7327 */
7328 while (parallel_workers > 0 &&
7329 maintenance_work_mem / (parallel_workers + 1) < 32 * 1024)
7330 parallel_workers--;
7331
7332done:
7334 table_close(heap, NoLock);
7335
7336 return parallel_workers;
7337}
int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers)
Definition allpaths.c:4973
uint32 BlockNumber
Definition block.h:31
#define Min(x, y)
Definition c.h:1131
bool is_parallel_safe(PlannerInfo *root, Node *node)
Definition clauses.c:782
int max_parallel_maintenance_workers
Definition globals.c:136
bool IsUnderPostmaster
Definition globals.c:122
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
#define NoLock
Definition lockdefs.h:34
void estimate_rel_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Definition plancat.c:1305
List * RelationGetIndexPredicate(Relation relation)
Definition relcache.c:5222
List * RelationGetIndexExpressions(Relation relation)
Definition relcache.c:5109
int rel_parallel_workers
Definition pathnodes.h:1103
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(), fb(), index_close(), index_open(), 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, 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 
)
extern

Definition at line 328 of file planner.c.

330{
332
333 if (planner_hook)
334 result = (*planner_hook) (parse, query_string, cursorOptions,
335 boundParams, es);
336 else
337 result = standard_planner(parse, query_string, cursorOptions,
338 boundParams, es);
339
340 pgstat_report_plan_id(result->planId, false);
341
342 return result;
343}
void pgstat_report_plan_id(int64 plan_id, bool force)
void parse(int)
Definition parse.c:49
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:346

References parse(), pgstat_report_plan_id(), planner_hook, result, and standard_planner().

Referenced by pg_plan_query(), and test_plan_advice_advisor().

◆ predicate_implied_by()

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

Definition at line 154 of file predtest.c.

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

References fb(), 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 
)
extern

Definition at line 224 of file predtest.c.

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

References fb(), 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 
)
extern

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:198
#define PVC_RECURSE_PLACEHOLDERS
Definition optimizer.h:202
#define PVC_RECURSE_WINDOWFUNCS
Definition optimizer.h:200
#define PVC_INCLUDE_WINDOWFUNCS
Definition optimizer.h:199
#define PVC_INCLUDE_PLACEHOLDERS
Definition optimizer.h:201
#define PVC_INCLUDE_AGGREGATES
Definition optimizer.h:197
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()

◆ pull_varnos()

Bitmapset * pull_varnos ( PlannerInfo root,
Node node 
)
extern

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
Relids varnos
Definition var.c:35
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition var.c:161

References fb(), 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 
)
extern

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 fb(), 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 
)
extern

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(), extract_lateral_vars_from_PHVs(), and generate_query_for_graph_path().

◆ var_is_nonnullable()

bool var_is_nonnullable ( PlannerInfo root,
Var var,
NotNullSource  source 
)
extern

Definition at line 4660 of file clauses.c.

4661{
4662 Assert(IsA(var, Var));
4663
4664 /* skip upper-level Vars */
4665 if (var->varlevelsup != 0)
4666 return false;
4667
4668 /* could the Var be nulled by any outer joins or grouping sets? */
4669 if (!bms_is_empty(var->varnullingrels))
4670 return false;
4671
4672 /*
4673 * If the Var has a non-default returning type, it could be NULL
4674 * regardless of any NOT NULL constraint. For example, OLD.col is NULL
4675 * for INSERT, and NEW.col is NULL for DELETE.
4676 */
4678 return false;
4679
4680 /* system columns cannot be NULL */
4681 if (var->varattno < 0)
4682 return true;
4683
4684 /* we don't trust whole-row Vars */
4685 if (var->varattno == 0)
4686 return false;
4687
4688 /* Check if the Var is defined as NOT NULL. */
4689 switch (source)
4690 {
4692 {
4693 /*
4694 * We retrieve the column NOT NULL constraint information from
4695 * the corresponding RelOptInfo.
4696 */
4697 RelOptInfo *rel;
4698 Bitmapset *notnullattnums;
4699
4700 rel = find_base_rel(root, var->varno);
4701 notnullattnums = rel->notnullattnums;
4702
4703 return bms_is_member(var->varattno, notnullattnums);
4704 }
4706 {
4707 /*
4708 * We retrieve the column NOT NULL constraint information from
4709 * the hash table.
4710 */
4712 Bitmapset *notnullattnums;
4713
4714 rte = planner_rt_fetch(var->varno, root);
4715
4716 /* We can only reason about ordinary relations */
4717 if (rte->rtekind != RTE_RELATION)
4718 return false;
4719
4720 /*
4721 * We must skip inheritance parent tables, as some child
4722 * tables may have a NOT NULL constraint for a column while
4723 * others may not. This cannot happen with partitioned
4724 * tables, though.
4725 */
4726 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4727 return false;
4728
4729 notnullattnums = find_relation_notnullatts(root, rte->relid);
4730
4731 return bms_is_member(var->varattno, notnullattnums);
4732 }
4734 {
4735 /*
4736 * We check the attnullability field in the tuple descriptor.
4737 * This is necessary rather than checking the attnotnull field
4738 * from the attribute relation, because attnotnull is also set
4739 * for invalid (NOT VALID) NOT NULL constraints, which do not
4740 * guarantee the absence of NULLs.
4741 */
4743 Relation rel;
4744 CompactAttribute *attr;
4745 bool result;
4746
4747 rte = planner_rt_fetch(var->varno, root);
4748
4749 /* We can only reason about ordinary relations */
4750 if (rte->rtekind != RTE_RELATION)
4751 return false;
4752
4753 /*
4754 * We must skip inheritance parent tables, as some child
4755 * tables may have a NOT NULL constraint for a column while
4756 * others may not. This cannot happen with partitioned
4757 * tables, though.
4758 *
4759 * Note that we need to check if the relation actually has any
4760 * children, as we might not have done that yet.
4761 */
4762 if (rte->inh && has_subclass(rte->relid) &&
4763 rte->relkind != RELKIND_PARTITIONED_TABLE)
4764 return false;
4765
4766 /* We need not lock the relation since it was already locked */
4767 rel = table_open(rte->relid, NoLock);
4769 var->varattno - 1);
4771 table_close(rel, NoLock);
4772
4773 return result;
4774 }
4775 default:
4776 elog(ERROR, "unrecognized NotNullSource: %d",
4777 (int) source);
4778 break;
4779 }
4780
4781 return false;
4782}
#define bms_is_empty(a)
Definition bitmapset.h:119
#define planner_rt_fetch(rti, root)
Definition pathnodes.h:704
bool has_subclass(Oid relationId)
Bitmapset * find_relation_notnullatts(PlannerInfo *root, Oid relid)
Definition plancat.c:763
@ VAR_RETURNING_DEFAULT
Definition primnodes.h:257
#define RelationGetDescr(relation)
Definition rel.h:542
char attnullability
Definition tupdesc.h:80
Bitmapset * notnullattnums
Definition pathnodes.h:1083
AttrNumber varattno
Definition primnodes.h:275
VarReturningType varreturningtype
Definition primnodes.h:298
#define ATTNULLABLE_VALID
Definition tupdesc.h:86
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195

References Assert, CompactAttribute::attnullability, ATTNULLABLE_VALID, bms_is_empty, bms_is_member(), elog, ERROR, fb(), find_base_rel(), find_relation_notnullatts(), has_subclass(), IsA, NoLock, NOTNULL_SOURCE_CATALOG, NOTNULL_SOURCE_HASHTABLE, NOTNULL_SOURCE_RELOPT, RelOptInfo::notnullattnums, planner_rt_fetch, RelationGetDescr, result, root, RTE_RELATION, source, table_close(), table_open(), TupleDescCompactAttr(), VAR_RETURNING_DEFAULT, Var::varattno, Var::varlevelsup, Var::varno, and Var::varreturningtype.

Referenced by expr_is_nonnullable().

Variable Documentation

◆ cpu_index_tuple_cost

PGDLLIMPORT double cpu_index_tuple_cost
extern

Definition at line 134 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 140 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 137 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 136 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 138 of file costsize.c.

Referenced by set_cte_size_estimates().

◆ seq_page_cost