PostgreSQL Source Code: src/include/utils/selfuncs.h File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | EstimationInfo |
struct | VariableStatData |
struct | GenericCosts |
Macros | |
---|---|
#define | DEFAULT_EQ_SEL 0.005 |
#define | DEFAULT_INEQ_SEL 0.3333333333333333 |
#define | DEFAULT_RANGE_INEQ_SEL 0.005 |
#define | DEFAULT_MULTIRANGE_INEQ_SEL 0.005 |
#define | DEFAULT_MATCH_SEL 0.005 |
#define | DEFAULT_MATCHING_SEL 0.010 |
#define | DEFAULT_NUM_DISTINCT 200 |
#define | DEFAULT_UNK_SEL 0.005 |
#define | DEFAULT_NOT_UNK_SEL (1.0 - DEFAULT_UNK_SEL) |
#define | CLAMP_PROBABILITY(p) |
#define | SELFLAG_USED_DEFAULT |
#define | ReleaseVariableStats(vardata) |
Typedefs | |
---|---|
typedef struct EstimationInfo | EstimationInfo |
typedef struct VariableStatData | VariableStatData |
typedef bool(* | get_relation_stats_hook_type) (PlannerInfo *root, RangeTblEntry *rte, AttrNumber attnum, VariableStatData *vardata) |
typedef bool(* | get_index_stats_hook_type) (PlannerInfo *root, Oid indexOid, AttrNumber indexattnum, VariableStatData *vardata) |
Functions | |
---|---|
void | examine_variable (PlannerInfo *root, Node *node, int varRelid, VariableStatData *vardata) |
bool | statistic_proc_security_check (VariableStatData *vardata, Oid func_oid) |
bool | get_restriction_variable (PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft) |
void | get_join_variables (PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo, VariableStatData *vardata1, VariableStatData *vardata2, bool *join_is_reversed) |
double | get_variable_numdistinct (VariableStatData *vardata, bool *isdefault) |
double | mcv_selectivity (VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, double *sumcommonp) |
double | histogram_selectivity (VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, int min_hist_size, int n_skip, int *hist_size) |
double | generic_restriction_selectivity (PlannerInfo *root, Oid oproid, Oid collation, List *args, int varRelid, double default_selectivity) |
double | ineq_histogram_selectivity (PlannerInfo *root, VariableStatData *vardata, Oid opoid, FmgrInfo *opproc, bool isgt, bool iseq, Oid collation, Datum constval, Oid consttype) |
double | var_eq_const (VariableStatData *vardata, Oid oproid, Oid collation, Datum constval, bool constisnull, bool varonleft, bool negate) |
double | var_eq_non_const (VariableStatData *vardata, Oid oproid, Oid collation, Node *other, bool varonleft, bool negate) |
Selectivity | boolvarsel (PlannerInfo *root, Node *arg, int varRelid) |
Selectivity | booltestsel (PlannerInfo *root, BoolTestType booltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo) |
Selectivity | nulltestsel (PlannerInfo *root, NullTestType nulltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo) |
Selectivity | scalararraysel (PlannerInfo *root, ScalarArrayOpExpr *clause, bool is_join_clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo) |
double | estimate_array_length (PlannerInfo *root, Node *arrayexpr) |
Selectivity | rowcomparesel (PlannerInfo *root, RowCompareExpr *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo) |
void | mergejoinscansel (PlannerInfo *root, Node *clause, Oid opfamily, CompareType cmptype, bool nulls_first, Selectivity *leftstart, Selectivity *leftend, Selectivity *rightstart, Selectivity *rightend) |
double | estimate_num_groups (PlannerInfo *root, List *groupExprs, double input_rows, List **pgset, EstimationInfo *estinfo) |
List * | estimate_multivariate_bucketsize (PlannerInfo *root, RelOptInfo *inner, List *hashclauses, Selectivity *innerbucketsize) |
void | estimate_hash_bucket_stats (PlannerInfo *root, Node *hashkey, double nbuckets, Selectivity *mcv_freq, Selectivity *bucketsize_frac) |
double | estimate_hashagg_tablesize (PlannerInfo *root, Path *path, const AggClauseCosts *agg_costs, double dNumGroups) |
List * | get_quals_from_indexclauses (List *indexclauses) |
Cost | index_other_operands_eval_cost (PlannerInfo *root, List *indexquals) |
List * | add_predicate_to_index_quals (IndexOptInfo *index, List *indexQuals) |
void | genericcostestimate (PlannerInfo *root, IndexPath *path, double loop_count, GenericCosts *costs) |
Selectivity | scalararraysel_containment (PlannerInfo *root, Node *leftop, Node *rightop, Oid elemtype, bool isEquality, bool useOr, int varRelid) |
◆ CLAMP_PROBABILITY
| #define CLAMP_PROBABILITY | ( | | p | ) | | -------------------------- | - | | - | - |
Value:
do { \
if (p < 0.0) \
p = 0.0; \
else if (p > 1.0) \
p = 1.0; \
} while (0)
Definition at line 63 of file selfuncs.h.
◆ DEFAULT_EQ_SEL
#define DEFAULT_EQ_SEL 0.005
◆ DEFAULT_INEQ_SEL
#define DEFAULT_INEQ_SEL 0.3333333333333333
◆ DEFAULT_MATCH_SEL
#define DEFAULT_MATCH_SEL 0.005
◆ DEFAULT_MATCHING_SEL
#define DEFAULT_MATCHING_SEL 0.010
◆ DEFAULT_MULTIRANGE_INEQ_SEL
#define DEFAULT_MULTIRANGE_INEQ_SEL 0.005
◆ DEFAULT_NOT_UNK_SEL
◆ DEFAULT_NUM_DISTINCT
#define DEFAULT_NUM_DISTINCT 200
◆ DEFAULT_RANGE_INEQ_SEL
#define DEFAULT_RANGE_INEQ_SEL 0.005
◆ DEFAULT_UNK_SEL
#define DEFAULT_UNK_SEL 0.005
◆ ReleaseVariableStats
| #define ReleaseVariableStats | ( | | vardata | ) | | ---------------------------- | - | | ------- | - |
Value:
do { \
(vardata).freefunc((vardata).statsTuple); \
} while(0)
#define HeapTupleIsValid(tuple)
Definition at line 100 of file selfuncs.h.
◆ SELFLAG_USED_DEFAULT
#define SELFLAG_USED_DEFAULT
◆ EstimationInfo
◆ get_index_stats_hook_type
◆ get_relation_stats_hook_type
◆ VariableStatData
◆ add_predicate_to_index_quals()
Definition at line 7158 of file selfuncs.c.
7159{
7160 List *predExtraQuals = NIL;
7162
7164 return indexQuals;
7165
7166 foreach(lc, index->indpred)
7167 {
7170
7172 predExtraQuals = list_concat(predExtraQuals, oneQual);
7173 }
7174 return list_concat(predExtraQuals, indexQuals);
7175}
List * list_concat(List *list1, const List *list2)
bool predicate_implied_by(List *predicate_list, List *clause_list, bool weak)
References lfirst, list_concat(), list_make1, NIL, and predicate_implied_by().
Referenced by btcostestimate(), genericcostestimate(), and gincostestimate().
◆ booltestsel()
Definition at line 1545 of file selfuncs.c.
1547{
1549 double selec;
1550
1552
1554 {
1556 double freq_null;
1558
1560 freq_null = stats->stanullfrac;
1561
1566 {
1567 double freq_true;
1568 double freq_false;
1569
1570
1571
1572
1574 freq_true = sslot.numbers[0];
1575 else
1576 freq_true = 1.0 - sslot.numbers[0] - freq_null;
1577
1578
1579
1580
1581
1582 freq_false = 1.0 - freq_true - freq_null;
1583
1584 switch (booltesttype)
1585 {
1587
1588 selec = freq_null;
1589 break;
1591
1592 selec = 1.0 - freq_null;
1593 break;
1595
1596 selec = freq_true;
1597 break;
1599
1600 selec = 1.0 - freq_true;
1601 break;
1603
1604 selec = freq_false;
1605 break;
1607
1608 selec = 1.0 - freq_false;
1609 break;
1610 default:
1611 elog(ERROR, "unrecognized booltesttype: %d",
1612 (int) booltesttype);
1613 selec = 0.0;
1614 break;
1615 }
1616
1618 }
1619 else
1620 {
1621
1622
1623
1624
1625
1626 switch (booltesttype)
1627 {
1629
1630 selec = freq_null;
1631 break;
1633
1634 selec = 1.0 - freq_null;
1635 break;
1638
1639 selec = (1.0 - freq_null) / 2.0;
1640 break;
1643
1644
1645 selec = (freq_null + 1.0) / 2.0;
1646 break;
1647 default:
1648 elog(ERROR, "unrecognized booltesttype: %d",
1649 (int) booltesttype);
1650 selec = 0.0;
1651 break;
1652 }
1653 }
1654 }
1655 else
1656 {
1657
1658
1659
1660
1661
1662
1663 switch (booltesttype)
1664 {
1667 break;
1670 break;
1674 varRelid,
1675 jointype, sjinfo);
1676 break;
1680 varRelid,
1681 jointype, sjinfo);
1682 break;
1683 default:
1684 elog(ERROR, "unrecognized booltesttype: %d",
1685 (int) booltesttype);
1686 selec = 0.0;
1687 break;
1688 }
1689 }
1690
1692
1693
1695
1697}
Selectivity clause_selectivity(PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
static void * GETSTRUCT(const HeapTupleData *tuple)
void free_attstatsslot(AttStatsSlot *sslot)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
FormData_pg_statistic * Form_pg_statistic
static bool DatumGetBool(Datum X)
void examine_variable(PlannerInfo *root, Node *node, int varRelid, VariableStatData *vardata)
#define DEFAULT_NOT_UNK_SEL
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
References arg, ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, CLAMP_PROBABILITY, clause_selectivity(), DatumGetBool(), DEFAULT_NOT_UNK_SEL, DEFAULT_UNK_SEL, elog, ERROR, examine_variable(), free_attstatsslot(), get_attstatsslot(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, IS_FALSE, IS_NOT_FALSE, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_TRUE, IS_UNKNOWN, AttStatsSlot::nnumbers, AttStatsSlot::numbers, ReleaseVariableStats, root, VariableStatData::statsTuple, and AttStatsSlot::values.
Referenced by clause_selectivity_ext().
◆ boolvarsel()
Definition at line 1517 of file selfuncs.c.
1518{
1520 double selec;
1521
1524 {
1525
1526
1527
1528
1531 }
1532 else
1533 {
1534
1535 selec = 0.5;
1536 }
1538 return selec;
1539}
static Datum BoolGetDatum(bool X)
double var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, Datum constval, bool constisnull, bool varonleft, bool negate)
References arg, BoolGetDatum(), examine_variable(), HeapTupleIsValid, InvalidOid, ReleaseVariableStats, root, VariableStatData::statsTuple, and var_eq_const().
Referenced by clause_selectivity_ext().
◆ estimate_array_length()
Definition at line 2144 of file selfuncs.c.
2145{
2146
2148
2149 if (arrayexpr && IsA(arrayexpr, Const))
2150 {
2151 Datum arraydatum = ((Const *) arrayexpr)->constvalue;
2152 bool arrayisnull = ((Const *) arrayexpr)->constisnull;
2154
2155 if (arrayisnull)
2156 return 0;
2159 }
2160 else if (arrayexpr && IsA(arrayexpr, ArrayExpr) &&
2161 !((ArrayExpr *) arrayexpr)->multidims)
2162 {
2164 }
2165 else if (arrayexpr && root)
2166 {
2167
2170 double nelem = 0;
2171
2174 {
2175
2176
2177
2178
2179
2180
2184 {
2188 }
2189 }
2191
2192 if (nelem > 0)
2193 return nelem;
2194 }
2195
2196
2197 return 10;
2198}
#define DatumGetArrayTypeP(X)
int ArrayGetNItems(int ndim, const int *dims)
double clamp_row_est(double nrows)
#define IsA(nodeptr, _type_)
static int list_length(const List *l)
static Node * strip_array_coercion(Node *node)
References ARR_DIMS, ARR_NDIM, ArrayGetNItems(), ATTSTATSSLOT_NUMBERS, clamp_row_est(), DatumGetArrayTypeP, examine_variable(), free_attstatsslot(), get_attstatsslot(), HeapTupleIsValid, InvalidOid, IsA, list_length(), AttStatsSlot::nnumbers, AttStatsSlot::numbers, ReleaseVariableStats, root, VariableStatData::statsTuple, and strip_array_coercion().
Referenced by array_unnest_support(), btcostestimate(), cost_qual_eval_walker(), cost_tidscan(), genericcostestimate(), and gincost_scalararrayopexpr().
◆ estimate_hash_bucket_stats()
Definition at line 4057 of file selfuncs.c.
4060{
4062 double estfract,
4063 ndistinct,
4064 stanullfrac,
4065 avgfreq;
4066 bool isdefault;
4068
4070
4071
4072 *mcv_freq = 0.0;
4073
4075 {
4079 {
4080
4081
4082
4084 *mcv_freq = sslot.numbers[0];
4086 }
4087 }
4088
4089
4091
4092
4093
4094
4095
4096 if (isdefault)
4097 {
4098 *bucketsize_frac = (Selectivity) Max(0.1, *mcv_freq);
4100 return;
4101 }
4102
4103
4105 {
4107
4109 stanullfrac = stats->stanullfrac;
4110 }
4111 else
4112 stanullfrac = 0.0;
4113
4114
4115 avgfreq = (1.0 - stanullfrac) / ndistinct;
4116
4117
4118
4119
4120
4121
4122
4123
4124
4126 {
4129 }
4130
4131
4132
4133
4134
4135
4136 if (ndistinct > nbuckets)
4137 estfract = 1.0 / nbuckets;
4138 else
4139 estfract = 1.0 / ndistinct;
4140
4141
4142
4143
4144 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
4145 estfract *= *mcv_freq / avgfreq;
4146
4147
4148
4149
4150
4151
4152 if (estfract < 1.0e-6)
4153 estfract = 1.0e-6;
4154 else if (estfract > 1.0)
4155 estfract = 1.0;
4156
4157 *bucketsize_frac = (Selectivity) estfract;
4158
4160}
double get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
References ATTSTATSSLOT_NUMBERS, clamp_row_est(), examine_variable(), free_attstatsslot(), get_attstatsslot(), get_variable_numdistinct(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, Max, AttStatsSlot::nnumbers, AttStatsSlot::numbers, VariableStatData::rel, ReleaseVariableStats, root, RelOptInfo::rows, VariableStatData::statsTuple, and RelOptInfo::tuples.
Referenced by final_cost_hashjoin().
◆ estimate_hashagg_tablesize()
◆ estimate_multivariate_bucketsize()
Definition at line 3798 of file selfuncs.c.
3801{
3803 List *otherclauses = NIL;
3804 double ndistinct = 1.0;
3805
3807
3808
3809
3810
3811
3812 return hashclauses;
3813
3814 while (clauses != NIL)
3815 {
3817 int relid = -1;
3819 List *origin_rinfos = NIL;
3820 double mvndistinct;
3821 List *origin_varinfos;
3822 int group_relid = -1;
3825 *lc2;
3826
3827
3828
3829
3830
3831
3832
3833 foreach(lc, clauses)
3834 {
3839
3840
3841
3842
3843
3844
3845 relids = rinfo->outer_is_left ?
3846 rinfo->right_relids : rinfo->left_relids;
3847 expr = rinfo->outer_is_left ?
3849
3851 root->simple_rel_array[relid]->statlist != NIL)
3852 {
3853 bool is_duplicate = false;
3854
3855
3856
3857
3858
3859 if (group_relid < 0)
3860 {
3862
3863 if (!rte || (rte->relkind != RELKIND_RELATION &&
3864 rte->relkind != RELKIND_MATVIEW &&
3865 rte->relkind != RELKIND_FOREIGN_TABLE &&
3866 rte->relkind != RELKIND_PARTITIONED_TABLE))
3867 {
3868
3869 otherclauses = lappend(otherclauses, rinfo);
3871 continue;
3872 }
3873
3874 group_relid = relid;
3875 group_rel = root->simple_rel_array[relid];
3876 }
3877 else if (group_relid != relid)
3878
3879
3880
3881
3882
3883 continue;
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3907
3908
3909
3910
3911
3912 foreach(lc1, varinfos)
3913 {
3915
3916 if ((expr, varinfo->var))
3917 continue;
3918
3919 is_duplicate = true;
3920 break;
3921 }
3922
3923 if (is_duplicate)
3924 {
3925
3926
3927
3928
3929 continue;
3930 }
3931
3932
3933
3934
3935
3936
3938 varinfo->var = expr;
3939 varinfo->rel = root->simple_rel_array[relid];
3940 varinfos = lappend(varinfos, varinfo);
3941
3942
3943
3944
3945
3946 origin_rinfos = lappend(origin_rinfos, rinfo);
3947 }
3948 else
3949 {
3950
3951 otherclauses = lappend(otherclauses, rinfo);
3952 }
3953
3955 }
3956
3958 {
3959
3960
3961
3962
3963 otherclauses = list_concat(otherclauses, origin_rinfos);
3966 continue;
3967 }
3968
3969 Assert(group_rel != NULL);
3970
3971
3972 origin_varinfos = varinfos;
3973 for (;;)
3974 {
3976 group_rel,
3977 &varinfos,
3978 &mvndistinct);
3979
3980 if (!estimated)
3981 break;
3982
3983
3984
3985
3986
3987
3988 if (ndistinct < mvndistinct)
3989 ndistinct = mvndistinct;
3990 Assert(ndistinct >= 1.0);
3991 }
3992
3994
3995
3996 forboth(lc1, origin_varinfos, lc2, origin_rinfos)
3997 {
3999
4001
4002 continue;
4003
4004
4005 otherclauses = lappend(otherclauses, lfirst(lc2));
4006 }
4007 }
4008
4009 *innerbucketsize = 1.0 / ndistinct;
4010 return otherclauses;
4011}
bool bms_get_singleton_member(const Bitmapset *a, int *member)
bool equal(const void *a, const void *b)
Assert(PointerIsAligned(start, uint64))
List * lappend(List *list, void *datum)
List * list_copy(const List *oldlist)
bool list_member_ptr(const List *list, const void *datum)
void list_free(List *list)
void list_free_deep(List *list)
void * palloc0(Size size)
static Node * get_rightop(const void *clause)
static Node * get_leftop(const void *clause)
#define lfirst_node(type, lc)
#define forboth(cell1, list1, cell2, list2)
#define foreach_delete_current(lst, var_or_cell)
Node * remove_nulling_relids(Node *node, const Bitmapset *removable_relids, const Bitmapset *except_relids)
static bool estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, List **varinfos, double *ndistinct)
References Assert(), bms_get_singleton_member(), RestrictInfo::clause, equal(), estimate_multivariate_ndistinct(), forboth, foreach_delete_current, get_leftop(), get_rightop(), lappend(), lfirst, lfirst_node, list_concat(), list_copy(), list_free(), list_free_deep(), list_length(), list_member_ptr(), NIL, palloc0(), GroupVarInfo::rel, remove_nulling_relids(), root, and GroupVarInfo::var.
Referenced by final_cost_hashjoin().
◆ estimate_num_groups()
Definition at line 3446 of file selfuncs.c.
3448{
3450 double srf_multiplier = 1.0;
3451 double numdistinct;
3453 int i;
3454
3455
3456 if (estinfo != NULL)
3458
3459
3460
3461
3462
3463
3464
3466
3467
3468
3469
3470
3471
3472 if (groupExprs == NIL || (pgset && *pgset == NIL))
3473 return 1.0;
3474
3475
3476
3477
3478
3479
3480
3481
3482 numdistinct = 1.0;
3483
3484 i = 0;
3485 foreach(l, groupExprs)
3486 {
3488 double this_srf_multiplier;
3490 List *varshere;
3492
3493
3495 continue;
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3509 if (srf_multiplier < this_srf_multiplier)
3510 srf_multiplier = this_srf_multiplier;
3511
3512
3513 if (exprType(groupexpr) == BOOLOID)
3514 {
3515 numdistinct *= 2.0;
3516 continue;
3517 }
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3534 {
3536 groupexpr, &vardata);
3538 continue;
3539 }
3541
3542
3543
3544
3545
3546
3547
3552
3553
3554
3555
3556
3557
3558
3559 if (varshere == NIL)
3560 {
3562 return input_rows;
3563 continue;
3564 }
3565
3566
3567
3568
3569 foreach(l2, varshere)
3570 {
3572
3576 }
3577 }
3578
3579
3580
3581
3582
3583 if (varinfos == NIL)
3584 {
3585
3586 numdistinct *= srf_multiplier;
3587
3588 numdistinct = ceil(numdistinct);
3589
3590 if (numdistinct > input_rows)
3591 numdistinct = input_rows;
3592 if (numdistinct < 1.0)
3593 numdistinct = 1.0;
3594 return numdistinct;
3595 }
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605 do
3606 {
3609 double reldistinct = 1;
3610 double relmaxndistinct = reldistinct;
3611 int relvarcount = 0;
3614
3615
3616
3617
3618
3619 relvarinfos = lappend(relvarinfos, varinfo1);
3621 {
3623
3624 if (varinfo2->rel == varinfo1->rel)
3625 {
3626
3627 relvarinfos = lappend(relvarinfos, varinfo2);
3628 }
3629 else
3630 {
3631
3632 newvarinfos = lappend(newvarinfos, varinfo2);
3633 }
3634 }
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648 while (relvarinfos)
3649 {
3650 double mvndistinct;
3651
3653 &mvndistinct))
3654 {
3655 reldistinct *= mvndistinct;
3656 if (relmaxndistinct < mvndistinct)
3657 relmaxndistinct = mvndistinct;
3658 relvarcount++;
3659 }
3660 else
3661 {
3662 foreach(l, relvarinfos)
3663 {
3665
3666 reldistinct *= varinfo2->ndistinct;
3667 if (relmaxndistinct < varinfo2->ndistinct)
3668 relmaxndistinct = varinfo2->ndistinct;
3669 relvarcount++;
3670
3671
3672
3673
3674
3675 if (estinfo != NULL && varinfo2->isdefault)
3677 }
3678
3679
3680 relvarinfos = NIL;
3681 }
3682 }
3683
3684
3685
3686
3688 if (rel->tuples > 0)
3689 {
3690
3691
3692
3693
3694
3695
3696
3697 double clamp = rel->tuples;
3698
3699 if (relvarcount > 1)
3700 {
3701 clamp *= 0.1;
3702 if (clamp < relmaxndistinct)
3703 {
3704 clamp = relmaxndistinct;
3705
3706 if (clamp > rel->tuples)
3707 clamp = rel->tuples;
3708 }
3709 }
3710 if (reldistinct > clamp)
3711 reldistinct = clamp;
3712
3713
3714
3715
3716
3717
3718 if (reldistinct > 0 && rel->rows < rel->tuples)
3719 {
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754 reldistinct *=
3756 rel->tuples / reldistinct));
3757 }
3759
3760
3761
3762
3763 numdistinct *= reldistinct;
3764 }
3765
3766 varinfos = newvarinfos;
3767 } while (varinfos != NIL);
3768
3769
3770 numdistinct *= srf_multiplier;
3771
3772
3773 numdistinct = ceil(numdistinct);
3774
3775
3776 if (numdistinct > input_rows)
3777 numdistinct = input_rows;
3778 if (numdistinct < 1.0)
3779 numdistinct = 1.0;
3780
3781 return numdistinct;
3782}
bool contain_volatile_functions(Node *clause)
double expression_returns_set_rows(PlannerInfo *root, Node *clause)
bool list_member_int(const List *list, int datum)
Oid exprType(const Node *expr)
#define PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_PLACEHOLDERS
#define PVC_RECURSE_WINDOWFUNCS
#define IS_SIMPLE_REL(rel)
#define for_each_from(cell, lst, N)
static List * add_unique_group_var(PlannerInfo *root, List *varinfos, Node *var, VariableStatData *vardata)
#define SELFLAG_USED_DEFAULT
List * pull_var_clause(Node *node, int flags)
References add_unique_group_var(), Assert(), clamp_row_est(), contain_volatile_functions(), estimate_multivariate_ndistinct(), examine_variable(), expression_returns_set_rows(), exprType(), EstimationInfo::flags, for_each_from, HeapTupleIsValid, i, IS_SIMPLE_REL, GroupVarInfo::isdefault, VariableStatData::isunique, lappend(), lfirst, linitial, list_member_int(), GroupVarInfo::ndistinct, NIL, pull_var_clause(), PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_WINDOWFUNCS, GroupVarInfo::rel, ReleaseVariableStats, root, RelOptInfo::rows, SELFLAG_USED_DEFAULT, VariableStatData::statsTuple, and RelOptInfo::tuples.
Referenced by adjust_rowcount_for_semijoins(), build_setop_child_paths(), cost_incremental_sort(), cost_memoize_rescan(), create_final_distinct_paths(), create_partial_distinct_paths(), create_unique_path(), estimate_path_cost_size(), get_number_of_groups(), and get_windowclause_startup_tuples().
◆ examine_variable()
Definition at line 5289 of file selfuncs.c.
5291{
5292 Node *basenode;
5296
5297
5299
5300
5302
5303
5304
5307 else
5308 basenode = node;
5309
5310
5311
5312 if (IsA(basenode, Var) &&
5313 (varRelid == 0 || varRelid == ((Var *) basenode)->varno))
5314 {
5315 Var *var = (Var *) basenode;
5316
5317
5318 vardata->var = basenode;
5320 vardata->atttype = var->vartype;
5321 vardata->atttypmod = var->vartypmod;
5323
5324
5326
5327 return;
5328 }
5329
5330
5331
5332
5333
5334
5337
5338 onerel = NULL;
5339
5341 {
5342
5343 }
5344 else
5345 {
5346 int relid;
5347
5348
5350 {
5351 if (varRelid == 0 || varRelid == relid)
5352 {
5354 vardata->rel = onerel;
5355 node = basenode;
5356 }
5357
5358 }
5359 else
5360 {
5361
5362 if (varRelid == 0)
5363 {
5364
5366 node = basenode;
5367 }
5369 {
5370
5372 node = basenode;
5373
5374 }
5375
5376 }
5377 }
5378
5380
5381 vardata->var = node;
5384
5385 if (onerel)
5386 {
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5402 Oid userid;
5403
5404
5405
5406
5407
5408
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5422
5423 foreach(ilist, onerel->indexlist)
5424 {
5427 int pos;
5428
5430 if (indexpr_item == NULL)
5431 continue;
5432
5433 for (pos = 0; pos < index->ncolumns; pos++)
5434 {
5435 if (index->indexkeys[pos] == 0)
5436 {
5437 Node *indexkey;
5438
5439 if (indexpr_item == NULL)
5440 elog(ERROR, "too few entries in indexprs list");
5441 indexkey = (Node *) lfirst(indexpr_item);
5444 if (equal(node, indexkey))
5445 {
5446
5447
5448
5449
5450 if (index->unique &&
5451 index->nkeycolumns == 1 &&
5452 pos == 0 &&
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5468 pos + 1, vardata))
5469 {
5470
5471
5472
5473
5474
5477 elog(ERROR, "no function provided to release variable stats with");
5478 }
5479 else if (index->indpred == NIL)
5480 {
5487
5489 {
5490
5492
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5506 rte->securityQuals == NIL &&
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526 if (!vardata->acl_ok &&
5527 root->append_rel_array != NULL)
5528 {
5531
5532 appinfo = root->append_rel_array[varno];
5533 while (appinfo &&
5536 {
5538 appinfo = root->append_rel_array[varno];
5539 }
5540 if (varno != index->rel->relid)
5541 {
5542
5545
5547 rte->securityQuals == NIL &&
5549 userid,
5551 }
5552 }
5553 }
5554 else
5555 {
5556
5557 vardata->acl_ok = true;
5558 }
5559 }
5561 break;
5562 }
5563 indexpr_item = lnext(index->indexprs, indexpr_item);
5564 }
5565 }
5567 break;
5568 }
5569
5570
5571
5572
5573
5574
5575
5576 foreach(slist, onerel->statlist)
5577 {
5581 int pos;
5582
5583
5584
5585
5586
5588 break;
5589
5590
5591 if (info->kind != STATS_EXT_EXPRESSIONS)
5592 continue;
5593
5594
5596 continue;
5597
5598 pos = 0;
5599 foreach(expr_item, info->exprs)
5600 {
5602
5604
5605
5608
5609
5610 if (equal(node, expr))
5611 {
5612
5613
5614
5615
5618
5620
5621
5622
5623
5624
5625
5626
5627
5628
5630 rte->securityQuals == NIL &&
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647 if (!vardata->acl_ok &&
5648 root->append_rel_array != NULL)
5649 {
5652
5653 appinfo = root->append_rel_array[varno];
5654 while (appinfo &&
5657 {
5659 appinfo = root->append_rel_array[varno];
5660 }
5661 if (varno != onerel->relid)
5662 {
5663
5666
5668 rte->securityQuals == NIL &&
5670 userid,
5672 }
5673 }
5674
5675 break;
5676 }
5677
5678 pos++;
5679 }
5680 }
5681 }
5682
5684}
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
#define MemSet(start, val, len)
#define OidIsValid(objectId)
HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx)
if(TABLE==NULL||TABLE_index==NULL)
int32 exprTypmod(const Node *expr)
#define planner_rt_fetch(rti, root)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
bool has_unique_index(RelOptInfo *rel, AttrNumber attno)
static Datum Int16GetDatum(int16 X)
static Datum ObjectIdGetDatum(Oid X)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * find_join_rel(PlannerInfo *root, Relids relids)
static void examine_simple_variable(PlannerInfo *root, Var *var, VariableStatData *vardata)
get_index_stats_hook_type get_index_stats_hook
static void ReleaseDummy(HeapTuple tuple)
void(* freefunc)(HeapTuple tuple)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Relids pull_varnos(PlannerInfo *root, Node *node)
References VariableStatData::acl_ok, ACL_SELECT, ACLCHECK_OK, arg, Assert(), VariableStatData::atttype, VariableStatData::atttypmod, bms_difference(), bms_free(), bms_get_singleton_member(), bms_is_empty, bms_is_member(), bms_overlap(), BoolGetDatum(), elog, equal(), ERROR, examine_simple_variable(), StatisticExtInfo::exprs, exprType(), exprTypmod(), find_base_rel(), find_join_rel(), VariableStatData::freefunc, get_index_stats_hook, GetUserId(), has_unique_index(), HeapTupleIsValid, if(), RelOptInfo::indexlist, RangeTblEntry::inh, StatisticExtInfo::inherit, Int16GetDatum(), IsA, VariableStatData::isunique, StatisticExtInfo::kind, lfirst, list_head(), lnext(), MemSet, NIL, ObjectIdGetDatum(), OidIsValid, AppendRelInfo::parent_relid, pg_class_aclcheck(), planner_rt_fetch, pull_varnos(), VariableStatData::rel, ReleaseDummy(), ReleaseSysCache(), RelOptInfo::relid, remove_nulling_relids(), root, RTE_RELATION, RangeTblEntry::rtekind, SearchSysCache3(), statext_expressions_load(), RelOptInfo::statlist, StatisticExtInfo::statOid, VariableStatData::statsTuple, RelOptInfo::userid, VariableStatData::var, Var::varattno, Var::varno, and VariableStatData::vartype.
Referenced by booltestsel(), boolvarsel(), estimate_array_length(), estimate_hash_bucket_stats(), estimate_num_groups(), get_join_variables(), get_restriction_variable(), mergejoinscansel(), nulltestsel(), and scalararraysel_containment().
◆ generic_restriction_selectivity()
double generic_restriction_selectivity | ( | PlannerInfo * | root, |
---|---|---|---|
Oid | oproid, | ||
Oid | collation, | ||
List * | args, | ||
int | varRelid, | ||
double | default_selectivity | ||
) |
Definition at line 919 of file selfuncs.c.
922{
923 double selec;
926 bool varonleft;
927
928
929
930
931
933 &vardata, &other, &varonleft))
934 return default_selectivity;
935
936
937
938
939
941 ((Const *) other)->constisnull)
942 {
944 return 0.0;
945 }
946
948 {
949
950 Datum constval = ((Const *) other)->constvalue;
952 double mcvsum;
953 double mcvsel;
954 double nullfrac;
955 int hist_size;
956
958
959
960
961
963 constval, varonleft,
964 &mcvsum);
965
966
967
968
969
970
971
973 constval, varonleft,
974 10, 1, &hist_size);
975 if (selec < 0)
976 {
977
978 selec = default_selectivity;
979 }
980 else if (hist_size < 100)
981 {
982
983
984
985
986
987 double hist_weight = hist_size / 100.0;
988
989 selec = selec * hist_weight +
990 default_selectivity * (1.0 - hist_weight);
991 }
992
993
994 if (selec < 0.0001)
995 selec = 0.0001;
996 else if (selec > 0.9999)
997 selec = 0.9999;
998
999
1002 else
1003 nullfrac = 0.0;
1004
1005
1006
1007
1008
1009
1010 selec *= 1.0 - nullfrac - mcvsum;
1011 selec += mcvsel;
1012 }
1013 else
1014 {
1015
1016 selec = default_selectivity;
1017 }
1018
1020
1021
1023
1024 return selec;
1025}
void fmgr_info(Oid functionId, FmgrInfo *finfo)
RegProcedure get_opcode(Oid opno)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, double *sumcommonp)
double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, int min_hist_size, int n_skip, int *hist_size)
References generate_unaccent_rules::args, CLAMP_PROBABILITY, fmgr_info(), get_opcode(), get_restriction_variable(), GETSTRUCT(), HeapTupleIsValid, histogram_selectivity(), IsA, mcv_selectivity(), ReleaseVariableStats, root, and VariableStatData::statsTuple.
Referenced by ltreeparentsel(), and matchingsel().
◆ genericcostestimate()
Definition at line 6935 of file selfuncs.c.
6939{
6943 Cost indexStartupCost;
6944 Cost indexTotalCost;
6946 double indexCorrelation;
6947 double numIndexPages;
6948 double numIndexTuples;
6949 double spc_random_page_cost;
6950 double num_sa_scans;
6951 double num_outer_scans;
6952 double num_scans;
6953 double qual_op_cost;
6954 double qual_arg_cost;
6955 List *selectivityQuals;
6957
6958
6959
6960
6961
6962
6964
6965
6966
6967
6968
6969
6971 if (num_sa_scans < 1)
6972 {
6973 num_sa_scans = 1;
6974 foreach(l, indexQuals)
6975 {
6977
6979 {
6982
6983 if (alength > 1)
6984 num_sa_scans *= alength;
6985 }
6986 }
6987 }
6988
6989
6991 index->rel->relid,
6993 NULL);
6994
6995
6996
6997
6998
6999
7001 if (numIndexTuples <= 0.0)
7002 {
7003 numIndexTuples = indexSelectivity * index->rel->tuples;
7004
7005
7006
7007
7008
7009
7010
7011
7012 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7013 }
7014
7015
7016
7017
7018
7019
7020 if (numIndexTuples > index->tuples)
7021 numIndexTuples = index->tuples;
7022 if (numIndexTuples < 1.0)
7023 numIndexTuples = 1.0;
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037 if (index->pages > 1 && index->tuples > 1)
7038 numIndexPages = ceil(numIndexTuples * index->pages / index->tuples);
7039 else
7040 numIndexPages = 1.0;
7041
7042
7044 &spc_random_page_cost,
7045 NULL);
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064 num_outer_scans = loop_count;
7065 num_scans = num_sa_scans * num_outer_scans;
7066
7067 if (num_scans > 1)
7068 {
7069 double pages_fetched;
7070
7071
7072 pages_fetched = numIndexPages * num_scans;
7073
7074
7077 (double) index->pages,
7079
7080
7081
7082
7083
7084
7085 indexTotalCost = (pages_fetched * spc_random_page_cost)
7086 / num_outer_scans;
7087 }
7088 else
7089 {
7090
7091
7092
7093
7094 indexTotalCost = numIndexPages * spc_random_page_cost;
7095 }
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7115
7116 indexStartupCost = qual_arg_cost;
7117 indexTotalCost += qual_arg_cost;
7118 indexTotalCost += numIndexTuples * num_sa_scans * (cpu_index_tuple_cost + qual_op_cost);
7119
7120
7121
7122
7123 indexCorrelation = 0.0;
7124
7125
7126
7127
7136}
Selectivity clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
double index_pages_fetched(double tuples_fetched, BlockNumber pages, double index_pages, PlannerInfo *root)
double cpu_index_tuple_cost
List * get_quals_from_indexclauses(List *indexclauses)
List * add_predicate_to_index_quals(IndexOptInfo *index, List *indexQuals)
double estimate_array_length(PlannerInfo *root, Node *arrayexpr)
Cost index_other_operands_eval_cost(PlannerInfo *root, List *indexquals)
void get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost, double *spc_seq_page_cost)
Selectivity indexSelectivity
double spc_random_page_cost
References add_predicate_to_index_quals(), ScalarArrayOpExpr::args, RestrictInfo::clause, clauselist_selectivity(), cpu_index_tuple_cost, cpu_operator_cost, estimate_array_length(), get_quals_from_indexclauses(), get_tablespace_page_costs(), index_other_operands_eval_cost(), index_pages_fetched(), IndexPath::indexclauses, GenericCosts::indexCorrelation, IndexPath::indexinfo, IndexPath::indexorderbys, GenericCosts::indexSelectivity, GenericCosts::indexStartupCost, GenericCosts::indexTotalCost, IsA, JOIN_INNER, lfirst, list_length(), lsecond, GenericCosts::num_sa_scans, GenericCosts::numIndexPages, GenericCosts::numIndexTuples, root, and GenericCosts::spc_random_page_cost.
Referenced by blcostestimate(), btcostestimate(), gistcostestimate(), hashcostestimate(), and spgcostestimate().
◆ get_join_variables()
Definition at line 5220 of file selfuncs.c.
5223{
5225 *right;
5226
5228 elog(ERROR, "join operator should take two arguments");
5229
5232
5235
5236 if (vardata1->rel &&
5238 *join_is_reversed = true;
5239 else if (vardata2->rel &&
5241 *join_is_reversed = true;
5242 else
5243 *join_is_reversed = false;
5244}
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
References generate_unaccent_rules::args, bms_is_subset(), elog, ERROR, examine_variable(), linitial, list_length(), lsecond, VariableStatData::rel, RelOptInfo::relids, root, SpecialJoinInfo::syn_lefthand, and SpecialJoinInfo::syn_righthand.
Referenced by eqjoinsel(), neqjoinsel(), and networkjoinsel().
◆ get_quals_from_indexclauses()
List * get_quals_from_indexclauses | ( | List * | indexclauses | ) |
---|
◆ get_restriction_variable()
Definition at line 5160 of file selfuncs.c.
5163{
5165 *right;
5167
5168
5170 return false;
5171
5174
5175
5176
5177
5178
5181
5182
5183
5184
5185 if (vardata->rel && rdata.rel == NULL)
5186 {
5187 *varonleft = true;
5189
5190 return true;
5191 }
5192
5193 if (vardata->rel == NULL && rdata.rel)
5194 {
5195 *varonleft = false;
5197
5198 *vardata = rdata;
5199 return true;
5200 }
5201
5202
5205
5206 return false;
5207}
Node * estimate_expression_value(PlannerInfo *root, Node *node)
References generate_unaccent_rules::args, estimate_expression_value(), examine_variable(), linitial, list_length(), lsecond, VariableStatData::rel, ReleaseVariableStats, root, and VariableStatData::var.
Referenced by _int_matchsel(), arraycontsel(), eqsel_internal(), generic_restriction_selectivity(), multirangesel(), networksel(), patternsel_common(), rangesel(), scalarineqsel_wrapper(), and tsmatchsel().
◆ get_variable_numdistinct()
double get_variable_numdistinct | ( | VariableStatData * | vardata, |
---|---|---|---|
bool * | isdefault | ||
) |
Definition at line 6149 of file selfuncs.c.
6150{
6151 double stadistinct;
6152 double stanullfrac = 0.0;
6153 double ntuples;
6154
6155 *isdefault = false;
6156
6157
6158
6159
6160
6161
6162
6164 {
6165
6167
6169 stadistinct = stats->stadistinct;
6170 stanullfrac = stats->stanullfrac;
6171 }
6172 else if (vardata->vartype == BOOLOID)
6173 {
6174
6175
6176
6177
6178
6179
6180 stadistinct = 2.0;
6181 }
6183 {
6184
6185
6186
6187
6188
6189
6190
6191 stadistinct = -1.0;
6192 }
6193 else
6194 {
6195
6196
6197
6198
6200 {
6201 switch (((Var *) vardata->var)->varattno)
6202 {
6204 stadistinct = -1.0;
6205 break;
6207 stadistinct = 1.0;
6208 break;
6209 default:
6210 stadistinct = 0.0;
6211 break;
6212 }
6213 }
6214 else
6215 stadistinct = 0.0;
6216
6217
6218
6219
6220 }
6221
6222
6223
6224
6225
6226
6227
6228
6230 stadistinct = -1.0 * (1.0 - stanullfrac);
6231
6232
6233
6234
6235 if (stadistinct > 0.0)
6237
6238
6239
6240
6241 if (vardata->rel == NULL)
6242 {
6243 *isdefault = true;
6245 }
6247 if (ntuples <= 0.0)
6248 {
6249 *isdefault = true;
6251 }
6252
6253
6254
6255
6256 if (stadistinct < 0.0)
6258
6259
6260
6261
6262
6263
6266
6267 *isdefault = true;
6269}
#define DEFAULT_NUM_DISTINCT
#define TableOidAttributeNumber
#define SelfItemPointerAttributeNumber
References clamp_row_est(), DEFAULT_NUM_DISTINCT, GETSTRUCT(), HeapTupleIsValid, IsA, VariableStatData::isunique, VariableStatData::rel, RTE_VALUES, RelOptInfo::rtekind, SelfItemPointerAttributeNumber, VariableStatData::statsTuple, TableOidAttributeNumber, RelOptInfo::tuples, VariableStatData::var, and VariableStatData::vartype.
Referenced by add_unique_group_var(), btcostestimate(), eqjoinsel(), estimate_hash_bucket_stats(), ineq_histogram_selectivity(), var_eq_const(), and var_eq_non_const().
◆ histogram_selectivity()
double histogram_selectivity | ( | VariableStatData * | vardata, |
---|---|---|---|
FmgrInfo * | opproc, | ||
Oid | collation, | ||
Datum | constval, | ||
bool | varonleft, | ||
int | min_hist_size, | ||
int | n_skip, | ||
int * | hist_size | ||
) |
Definition at line 828 of file selfuncs.c.
833{
834 double result;
836
837
839 Assert(min_hist_size > 2 * n_skip);
840
844 STATISTIC_KIND_HISTOGRAM, InvalidOid,
846 {
847 *hist_size = sslot.nvalues;
848 if (sslot.nvalues >= min_hist_size)
849 {
851 int nmatch = 0;
852 int i;
853
854
855
856
857
858
859
860
861
863 NULL, NULL);
864 fcinfo->args[0].isnull = false;
865 fcinfo->args[1].isnull = false;
866
867 if (varonleft)
868 fcinfo->args[1].value = constval;
869 else
870 fcinfo->args[0].value = constval;
871
872 for (i = n_skip; i < sslot.nvalues - n_skip; i++)
873 {
875
876 if (varonleft)
877 fcinfo->args[0].value = sslot.values[i];
878 else
879 fcinfo->args[1].value = sslot.values[i];
880 fcinfo->isnull = false;
882 if (!fcinfo->isnull && DatumGetBool(fresult))
883 nmatch++;
884 }
885 result = ((double) nmatch) / ((double) (sslot.nvalues - 2 * n_skip));
886 }
887 else
888 result = -1;
890 }
891 else
892 {
893 *hist_size = 0;
894 result = -1;
895 }
896
897 return result;
898}
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
References Assert(), ATTSTATSSLOT_VALUES, DatumGetBool(), FmgrInfo::fn_oid, free_attstatsslot(), FunctionCallInvoke, get_attstatsslot(), HeapTupleIsValid, i, InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, AttStatsSlot::nvalues, statistic_proc_security_check(), VariableStatData::statsTuple, and AttStatsSlot::values.
Referenced by generic_restriction_selectivity(), and patternsel_common().
◆ index_other_operands_eval_cost()
Definition at line 6881 of file selfuncs.c.
6882{
6883 Cost qual_arg_cost = 0;
6885
6886 foreach(lc, indexquals)
6887 {
6889 Node *other_operand;
6891
6892
6893
6894
6895
6898
6900 {
6902
6904 }
6906 {
6908
6909 other_operand = (Node *) rc->rargs;
6910 }
6912 {
6914
6916 }
6918 {
6919 other_operand = NULL;
6920 }
6921 else
6922 {
6923 elog(ERROR, "unsupported indexqual type: %d",
6925 other_operand = NULL;
6926 }
6927
6929 qual_arg_cost += index_qual_cost.startup + index_qual_cost.per_tuple;
6930 }
6931 return qual_arg_cost;
6932}
void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)
References OpExpr::args, ScalarArrayOpExpr::args, cost_qual_eval_node(), elog, ERROR, IsA, lfirst, lsecond, nodeTag, QualCost::per_tuple, RowCompareExpr::rargs, root, and QualCost::startup.
Referenced by brincostestimate(), genericcostestimate(), and gincostestimate().
◆ ineq_histogram_selectivity()
Definition at line 1046 of file selfuncs.c.
1051{
1052 double hist_selec;
1054
1055 hist_selec = -1.0;
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1072 STATISTIC_KIND_HISTOGRAM, InvalidOid,
1074 {
1075 if (sslot.nvalues > 1 &&
1076 sslot.stacoll == collation &&
1078 {
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 double histfrac;
1098 int lobound = 0;
1099 int hibound = sslot.nvalues;
1100 bool have_end = false;
1101
1102
1103
1104
1105
1106
1107
1110 vardata,
1112 collation,
1115
1116 while (lobound < hibound)
1117 {
1118 int probe = (lobound + hibound) / 2;
1119 bool ltcmp;
1120
1121
1122
1123
1124
1125
1126 if (probe == 0 && sslot.nvalues > 2)
1128 vardata,
1130 collation,
1132 NULL);
1133 else if (probe == sslot.nvalues - 1 && sslot.nvalues > 2)
1135 vardata,
1137 collation,
1138 NULL,
1139 &sslot.values[probe]);
1140
1142 collation,
1143 sslot.values[probe],
1144 constval));
1145 if (isgt)
1146 ltcmp = !ltcmp;
1147 if (ltcmp)
1148 lobound = probe + 1;
1149 else
1150 hibound = probe;
1151 }
1152
1153 if (lobound <= 0)
1154 {
1155
1156
1157
1158
1159
1160
1161
1162
1163 histfrac = 0.0;
1164 }
1165 else if (lobound >= sslot.nvalues)
1166 {
1167
1168
1169
1170 histfrac = 1.0;
1171 }
1172 else
1173 {
1174
1175 int i = lobound;
1176 double eq_selec = 0;
1177 double val,
1178 high,
1179 low;
1180 double binfrac;
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 if (i == 1 || isgt == iseq)
1199 {
1200 double otherdistinct;
1201 bool isdefault;
1203
1204
1206 &isdefault);
1207
1208
1212 {
1213 otherdistinct -= mcvslot.nnumbers;
1215 }
1216
1217
1218 if (otherdistinct > 1)
1219 eq_selec = 1.0 / otherdistinct;
1220 }
1221
1222
1223
1224
1225
1226
1231 &low, &high))
1232 {
1233 if (high <= low)
1234 {
1235
1236 binfrac = 0.5;
1237 }
1238 else if (val <= low)
1239 binfrac = 0.0;
1240 else if (val >= high)
1241 binfrac = 1.0;
1242 else
1243 {
1244 binfrac = (val - low) / (high - low);
1245
1246
1247
1248
1249
1250
1251
1252 if (isnan(binfrac) ||
1253 binfrac < 0.0 || binfrac > 1.0)
1254 binfrac = 0.5;
1255 }
1256 }
1257 else
1258 {
1259
1260
1261
1262
1263
1264
1265
1266
1267 binfrac = 0.5;
1268 }
1269
1270
1271
1272
1273
1274
1275 histfrac = (double) (i - 1) + binfrac;
1276 histfrac /= (double) (sslot.nvalues - 1);
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310 if (i == 1)
1311 histfrac += eq_selec * (1.0 - binfrac);
1312
1313
1314
1315
1316
1317
1318 if (isgt == iseq)
1319 histfrac -= eq_selec;
1320 }
1321
1322
1323
1324
1325
1326 hist_selec = isgt ? (1.0 - histfrac) : histfrac;
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 if (have_end)
1339 else
1340 {
1341 double cutoff = 0.01 / (double) (sslot.nvalues - 1);
1342
1343 if (hist_selec < cutoff)
1344 hist_selec = cutoff;
1345 else if (hist_selec > 1.0 - cutoff)
1346 hist_selec = 1.0 - cutoff;
1347 }
1348 }
1349 else if (sslot.nvalues > 1)
1350 {
1351
1352
1353
1354
1355
1356
1357
1359 int nmatch = 0;
1360
1362 NULL, NULL);
1363 fcinfo->args[0].isnull = false;
1364 fcinfo->args[1].isnull = false;
1365 fcinfo->args[1].value = constval;
1366 for (int i = 0; i < sslot.nvalues; i++)
1367 {
1369
1370 fcinfo->args[0].value = sslot.values[i];
1371 fcinfo->isnull = false;
1373 if (!fcinfo->isnull && DatumGetBool(fresult))
1374 nmatch++;
1375 }
1376 hist_selec = ((double) nmatch) / ((double) sslot.nvalues);
1377
1378
1379
1380
1381
1382
1383
1384 {
1385 double cutoff = 0.01 / (double) (sslot.nvalues - 1);
1386
1387 if (hist_selec < cutoff)
1388 hist_selec = cutoff;
1389 else if (hist_selec > 1.0 - cutoff)
1390 hist_selec = 1.0 - cutoff;
1391 }
1392 }
1393
1395 }
1396
1397 return hist_selec;
1398}
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
bool comparison_ops_are_compatible(Oid opno1, Oid opno2)
static bool convert_to_scalar(Datum value, Oid valuetypid, Oid collid, double *scaledvalue, Datum lobound, Datum hibound, Oid boundstypid, double *scaledlobound, double *scaledhibound)
static bool get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop, Oid collation, Datum *min, Datum *max)
References ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, CLAMP_PROBABILITY, comparison_ops_are_compatible(), convert_to_scalar(), DatumGetBool(), FmgrInfo::fn_oid, free_attstatsslot(), FunctionCall2Coll(), FunctionCallInvoke, get_actual_variable_range(), get_attstatsslot(), get_variable_numdistinct(), HeapTupleIsValid, i, InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, AttStatsSlot::nnumbers, AttStatsSlot::nvalues, root, AttStatsSlot::stacoll, AttStatsSlot::staop, statistic_proc_security_check(), VariableStatData::statsTuple, val, AttStatsSlot::values, and VariableStatData::vartype.
Referenced by prefix_selectivity(), and scalarineqsel().
◆ mcv_selectivity()
Definition at line 737 of file selfuncs.c.
740{
741 double mcv_selec,
742 sumcommon;
744 int i;
745
746 mcv_selec = 0.0;
747 sumcommon = 0.0;
748
754 {
756
757
758
759
760
761
762
763
765 NULL, NULL);
766 fcinfo->args[0].isnull = false;
767 fcinfo->args[1].isnull = false;
768
769 if (varonleft)
770 fcinfo->args[1].value = constval;
771 else
772 fcinfo->args[0].value = constval;
773
775 {
777
778 if (varonleft)
779 fcinfo->args[0].value = sslot.values[i];
780 else
781 fcinfo->args[1].value = sslot.values[i];
782 fcinfo->isnull = false;
784 if (!fcinfo->isnull && DatumGetBool(fresult))
785 mcv_selec += sslot.numbers[i];
786 sumcommon += sslot.numbers[i];
787 }
789 }
790
791 *sumcommonp = sumcommon;
792 return mcv_selec;
793}
References ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, DatumGetBool(), FmgrInfo::fn_oid, free_attstatsslot(), FunctionCallInvoke, get_attstatsslot(), HeapTupleIsValid, i, InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, AttStatsSlot::numbers, AttStatsSlot::nvalues, statistic_proc_security_check(), VariableStatData::statsTuple, and AttStatsSlot::values.
Referenced by generic_restriction_selectivity(), networksel(), patternsel_common(), and scalarineqsel().
◆ mergejoinscansel()
Definition at line 2960 of file selfuncs.c.
2964{
2966 *right;
2968 rightvar;
2969 Oid opmethod;
2970 int op_strategy;
2971 Oid op_lefttype;
2972 Oid op_righttype;
2973 Oid opno,
2974 collation,
2975 lsortop,
2976 rsortop,
2977 lstatop,
2978 rstatop,
2979 ltop,
2980 leop,
2981 revltop,
2982 revleop;
2984 lestrat,
2985 gtstrat,
2986 gestrat;
2987 bool isgt;
2989 leftmax,
2990 rightmin,
2991 rightmax;
2992 double selec;
2993
2994
2995
2996 *leftstart = *rightstart = 0.0;
2997 *leftend = *rightend = 1.0;
2998
2999
3001 return;
3002 opno = ((OpExpr *) clause)->opno;
3003 collation = ((OpExpr *) clause)->inputcollid;
3006 if (!right)
3007 return;
3008
3009
3012
3014
3015
3017 &op_strategy,
3018 &op_lefttype,
3019 &op_righttype);
3021
3022
3023
3024
3025
3026
3027
3028
3029 switch (cmptype)
3030 {
3032 isgt = false;
3035 if (op_lefttype == op_righttype)
3036 {
3037
3039 op_lefttype, op_righttype,
3040 ltstrat);
3042 op_lefttype, op_righttype,
3043 lestrat);
3044 lsortop = ltop;
3045 rsortop = ltop;
3046 lstatop = lsortop;
3047 rstatop = rsortop;
3048 revltop = ltop;
3049 revleop = leop;
3050 }
3051 else
3052 {
3054 op_lefttype, op_righttype,
3055 ltstrat);
3057 op_lefttype, op_righttype,
3058 lestrat);
3060 op_lefttype, op_lefttype,
3061 ltstrat);
3063 op_righttype, op_righttype,
3064 ltstrat);
3065 lstatop = lsortop;
3066 rstatop = rsortop;
3068 op_righttype, op_lefttype,
3069 ltstrat);
3071 op_righttype, op_lefttype,
3072 lestrat);
3073 }
3074 break;
3076
3077 isgt = true;
3081 if (op_lefttype == op_righttype)
3082 {
3083
3085 op_lefttype, op_righttype,
3086 gtstrat);
3088 op_lefttype, op_righttype,
3089 gestrat);
3090 lsortop = ltop;
3091 rsortop = ltop;
3093 op_lefttype, op_lefttype,
3094 ltstrat);
3095 rstatop = lstatop;
3096 revltop = ltop;
3097 revleop = leop;
3098 }
3099 else
3100 {
3102 op_lefttype, op_righttype,
3103 gtstrat);
3105 op_lefttype, op_righttype,
3106 gestrat);
3108 op_lefttype, op_lefttype,
3109 gtstrat);
3111 op_righttype, op_righttype,
3112 gtstrat);
3114 op_lefttype, op_lefttype,
3115 ltstrat);
3117 op_righttype, op_righttype,
3118 ltstrat);
3120 op_righttype, op_lefttype,
3121 gtstrat);
3123 op_righttype, op_lefttype,
3124 gestrat);
3125 }
3126 break;
3127 default:
3128 goto fail;
3129 }
3130
3139 goto fail;
3140
3141
3142 if (!isgt)
3143 {
3145 &leftmin, &leftmax))
3146 goto fail;
3148 &rightmin, &rightmax))
3149 goto fail;
3150 }
3151 else
3152 {
3153
3155 &leftmax, &leftmin))
3156 goto fail;
3158 &rightmax, &rightmin))
3159 goto fail;
3160 }
3161
3162
3163
3164
3165
3166
3167 selec = scalarineqsel(root, leop, isgt, true, collation, &leftvar,
3168 rightmax, op_righttype);
3170 *leftend = selec;
3171
3172
3173 selec = scalarineqsel(root, revleop, isgt, true, collation, &rightvar,
3174 leftmax, op_lefttype);
3176 *rightend = selec;
3177
3178
3179
3180
3181
3182
3183
3184 if (*leftend > *rightend)
3185 *leftend = 1.0;
3186 else if (*leftend < *rightend)
3187 *rightend = 1.0;
3188 else
3189 *leftend = *rightend = 1.0;
3190
3191
3192
3193
3194
3195
3196
3197 selec = scalarineqsel(root, ltop, isgt, false, collation, &leftvar,
3198 rightmin, op_righttype);
3200 *leftstart = selec;
3201
3202
3203 selec = scalarineqsel(root, revltop, isgt, false, collation, &rightvar,
3204 leftmin, op_lefttype);
3206 *rightstart = selec;
3207
3208
3209
3210
3211
3212
3213
3214 if (*leftstart < *rightstart)
3215 *leftstart = 0.0;
3216 else if (*leftstart > *rightstart)
3217 *rightstart = 0.0;
3218 else
3219 *leftstart = *rightstart = 0.0;
3220
3221
3222
3223
3224
3225
3226
3227 if (nulls_first)
3228 {
3230
3232 {
3234 *leftstart += stats->stanullfrac;
3236 *leftend += stats->stanullfrac;
3238 }
3240 {
3242 *rightstart += stats->stanullfrac;
3244 *rightend += stats->stanullfrac;
3246 }
3247 }
3248
3249
3250 if (*leftstart >= *leftend)
3251 {
3252 *leftstart = 0.0;
3253 *leftend = 1.0;
3254 }
3255 if (*rightstart >= *rightend)
3256 {
3257 *rightstart = 0.0;
3258 *rightend = 1.0;
3259 }
3260
3261fail:
3264}
StrategyNumber IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, bool missing_ok)
CompareType IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, bool missing_ok)
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Oid get_opfamily_method(Oid opfid)
static bool is_opclause(const void *clause)
static bool get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop, Oid collation, Datum *min, Datum *max)
static double scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, Oid collation, VariableStatData *vardata, Datum constval, Oid consttype)
References Assert(), CLAMP_PROBABILITY, COMPARE_EQ, COMPARE_GE, COMPARE_GT, COMPARE_LE, COMPARE_LT, DEFAULT_INEQ_SEL, examine_variable(), get_leftop(), get_op_opfamily_properties(), get_opfamily_member(), get_opfamily_method(), get_rightop(), get_variable_range(), GETSTRUCT(), HeapTupleIsValid, IndexAmTranslateCompareType(), IndexAmTranslateStrategy(), is_opclause(), OidIsValid, ReleaseVariableStats, root, scalarineqsel(), and VariableStatData::statsTuple.
Referenced by cached_scansel().
◆ nulltestsel()
Definition at line 1703 of file selfuncs.c.
1705{
1707 double selec;
1708
1710
1712 {
1714 double freq_null;
1715
1717 freq_null = stats->stanullfrac;
1718
1719 switch (nulltesttype)
1720 {
1722
1723
1724
1725
1726 selec = freq_null;
1727 break;
1729
1730
1731
1732
1733
1734 selec = 1.0 - freq_null;
1735 break;
1736 default:
1737 elog(ERROR, "unrecognized nulltesttype: %d",
1738 (int) nulltesttype);
1739 return (Selectivity) 0;
1740 }
1741 }
1742 else if (vardata.var && IsA(vardata.var, Var) &&
1743 ((Var *) vardata.var)->varattno < 0)
1744 {
1745
1746
1747
1748
1749 selec = (nulltesttype == IS_NULL) ? 0.0 : 1.0;
1750 }
1751 else
1752 {
1753
1754
1755
1756 switch (nulltesttype)
1757 {
1760 break;
1763 break;
1764 default:
1765 elog(ERROR, "unrecognized nulltesttype: %d",
1766 (int) nulltesttype);
1767 return (Selectivity) 0;
1768 }
1769 }
1770
1772
1773
1775
1777}
References arg, CLAMP_PROBABILITY, DEFAULT_NOT_UNK_SEL, DEFAULT_UNK_SEL, elog, ERROR, examine_variable(), GETSTRUCT(), HeapTupleIsValid, IS_NOT_NULL, IS_NULL, IsA, ReleaseVariableStats, root, VariableStatData::statsTuple, and VariableStatData::var.
Referenced by clause_selectivity_ext(), and clauselist_selectivity_ext().
◆ rowcomparesel()
Definition at line 2210 of file selfuncs.c.
2213{
2217 List *opargs;
2218 bool is_join_clause;
2219
2220
2222
2223
2224
2225
2226
2227
2228 if (varRelid != 0)
2229 {
2230
2231
2232
2233
2234 is_join_clause = false;
2235 }
2236 else if (sjinfo == NULL)
2237 {
2238
2239
2240
2241
2242 is_join_clause = false;
2243 }
2244 else
2245 {
2246
2247
2248
2250 }
2251
2252 if (is_join_clause)
2253 {
2254
2256 opargs,
2257 inputcollid,
2258 jointype,
2259 sjinfo);
2260 }
2261 else
2262 {
2263
2265 opargs,
2266 inputcollid,
2267 varRelid);
2268 }
2269
2270 return s1;
2271}
int NumRelids(PlannerInfo *root, Node *clause)
#define list_make2(x1, x2)
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
References join_selectivity(), RowCompareExpr::largs, linitial, linitial_oid, list_make2, NumRelids(), RowCompareExpr::rargs, restriction_selectivity(), root, and s1.
Referenced by clause_selectivity_ext().
◆ scalararraysel()
Definition at line 1821 of file selfuncs.c.
1827{
1828 Oid operator = clause->opno;
1829 bool useOr = clause->useOr;
1830 bool isEquality = false;
1831 bool isInequality = false;
1832 Node *leftop;
1833 Node *rightop;
1834 Oid nominal_element_type;
1835 Oid nominal_element_collation;
1841
1842
1846
1847
1850
1851
1853 if ((nominal_element_type))
1854 return (Selectivity) 0.5;
1855
1856 nominal_element_collation = exprCollation(rightop);
1857
1858
1860
1861
1862
1863
1864
1867 {
1868 if (operator == typentry->eq_opr)
1869 isEquality = true;
1871 isInequality = true;
1872 }
1873
1874
1875
1876
1877
1878
1879
1880 if ((isEquality || isInequality) && !is_join_clause)
1881 {
1883 nominal_element_type,
1884 isEquality, useOr, varRelid);
1885 if (s1 >= 0.0)
1886 return s1;
1887 }
1888
1889
1890
1891
1892
1893 if (is_join_clause)
1895 else
1897 if (!oprsel)
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909 if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
1910 isEquality = true;
1911 else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
1912 isInequality = true;
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926 if (rightop && IsA(rightop, Const))
1927 {
1928 Datum arraydatum = ((Const *) rightop)->constvalue;
1929 bool arrayisnull = ((Const *) rightop)->constisnull;
1932 bool elmbyval;
1933 char elmalign;
1934 int num_elems;
1935 Datum *elem_values;
1936 bool *elem_nulls;
1937 int i;
1938
1939 if (arrayisnull)
1943 &elmlen, &elmbyval, &elmalign);
1946 elmlen, elmbyval, elmalign,
1947 &elem_values, &elem_nulls, &num_elems);
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
1964
1965 for (i = 0; i < num_elems; i++)
1966 {
1969
1972 -1,
1973 nominal_element_collation,
1974 elmlen,
1975 elem_values[i],
1976 elem_nulls[i],
1977 elmbyval));
1978 if (is_join_clause)
1980 clause->inputcollid,
1986 else
1988 clause->inputcollid,
1993
1994 if (useOr)
1995 {
1997 if (isEquality)
1998 s1disjoint += s2;
1999 }
2000 else
2001 {
2003 if (isInequality)
2004 s1disjoint += s2 - 1.0;
2005 }
2006 }
2007
2008
2009 if ((useOr ? isEquality : isInequality) &&
2010 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2011 s1 = s1disjoint;
2012 }
2013 else if (rightop && IsA(rightop, ArrayExpr) &&
2014 !((ArrayExpr *) rightop)->multidims)
2015 {
2018 bool elmbyval;
2020
2022 &elmlen, &elmbyval);
2023
2024
2025
2026
2027
2028
2029
2030
2031 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2032
2033 foreach(l, arrayexpr->elements)
2034 {
2038
2039
2040
2041
2042
2043
2045 if (is_join_clause)
2047 clause->inputcollid,
2053 else
2055 clause->inputcollid,
2060
2061 if (useOr)
2062 {
2064 if (isEquality)
2065 s1disjoint += s2;
2066 }
2067 else
2068 {
2070 if (isInequality)
2071 s1disjoint += s2 - 1.0;
2072 }
2073 }
2074
2075
2076 if ((useOr ? isEquality : isInequality) &&
2077 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2078 s1 = s1disjoint;
2079 }
2080 else
2081 {
2085 int i;
2086
2087
2088
2089
2090
2091
2093 dummyexpr->typeId = nominal_element_type;
2094 dummyexpr->typeMod = -1;
2095 dummyexpr->collation = clause->inputcollid;
2097 if (is_join_clause)
2099 clause->inputcollid,
2105 else
2107 clause->inputcollid,
2112 s1 = useOr ? 0.0 : 1.0;
2113
2114
2115
2116
2117
2118
2120 {
2121 if (useOr)
2123 else
2125 }
2126 }
2127
2128
2130
2131 return s1;
2132}
Selectivity scalararraysel_containment(PlannerInfo *root, Node *leftop, Node *rightop, Oid elemtype, bool isEquality, bool useOr, int varRelid)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)
RegProcedure get_oprrest(Oid opno)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_oprjoin(Oid opno)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Oid get_base_element_type(Oid typid)
Oid get_negator(Oid opno)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Oid exprCollation(const Node *expr)
static Datum PointerGetDatum(const void *X)
static float8 DatumGetFloat8(Datum X)
static Datum Int32GetDatum(int32 X)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
References generate_unaccent_rules::args, ScalarArrayOpExpr::args, ARR_ELEMTYPE, Assert(), CLAMP_PROBABILITY, DatumGetArrayTypeP, DatumGetFloat8(), deconstruct_array(), TypeCacheEntry::eq_opr, estimate_expression_value(), exprCollation(), exprType(), fmgr_info(), FunctionCall4Coll(), FunctionCall5Coll(), get_base_element_type(), get_negator(), get_oprjoin(), get_oprrest(), get_typlenbyval(), get_typlenbyvalalign(), i, Int16GetDatum(), Int32GetDatum(), IsA, lfirst, linitial, list_length(), list_make2, lookup_type_cache(), lsecond, makeConst(), makeNode, ObjectIdGetDatum(), OidIsValid, ScalarArrayOpExpr::opno, PointerGetDatum(), root, s1, s2, scalararraysel_containment(), strip_array_coercion(), TYPECACHE_EQ_OPR, CaseTestExpr::typeId, and ScalarArrayOpExpr::useOr.
Referenced by clause_selectivity_ext().
◆ scalararraysel_containment()
Definition at line 81 of file array_selfuncs.c.
85{
91
92
93
94
96 if (!vardata.rel)
97 {
99 return -1.0;
100 }
101
102
103
104
106 {
108 return -1.0;
109 }
110 if (((Const *) leftop)->constisnull)
111 {
112
115 }
116 constval = ((Const *) leftop)->constvalue;
117
118
121 {
123 return -1.0;
124 }
126
127
128
129
130 if (!isEquality)
131 useOr = !useOr;
132
133
136 {
140
142
143
147 {
148
149 if (useOr ||
153 memset(&hslot, 0, sizeof(hslot));
154
155
156
157
158
159
160 if (useOr)
165 &constval, 1,
166 OID_ARRAY_CONTAINS_OP,
167 typentry);
168 else
173 &constval, 1,
176 OID_ARRAY_CONTAINED_OP,
177 typentry);
178
181 }
182 else
183 {
184
185 if (useOr)
187 NULL, 0,
188 &constval, 1,
189 OID_ARRAY_CONTAINS_OP,
190 typentry);
191 else
193 NULL, 0,
194 &constval, 1,
195 NULL, 0,
196 OID_ARRAY_CONTAINED_OP,
197 typentry);
198 }
199
200
201
202
203 selec *= (1.0 - stats->stanullfrac);
204 }
205 else
206 {
207
208 if (useOr)
210 NULL, 0,
211 &constval, 1,
212 OID_ARRAY_CONTAINS_OP,
213 typentry);
214 else
216 NULL, 0,
217 &constval, 1,
218 NULL, 0,
219 OID_ARRAY_CONTAINED_OP,
220 typentry);
221
222 }
223
225
226
227
228
229 if (!isEquality)
230 selec = 1.0 - selec;
231
233
234 return selec;
235}
static Selectivity mcelem_array_contained_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, float4 *hist, int nhist, Oid operator, TypeCacheEntry *typentry)
static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, Oid operator, TypeCacheEntry *typentry)
#define TYPECACHE_CMP_PROC_FINFO
References ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, CLAMP_PROBABILITY, TypeCacheEntry::cmp_proc_finfo, examine_variable(), FmgrInfo::fn_oid, free_attstatsslot(), get_attstatsslot(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, IsA, lookup_type_cache(), mcelem_array_contain_overlap_selec(), mcelem_array_contained_selec(), AttStatsSlot::nnumbers, AttStatsSlot::numbers, AttStatsSlot::nvalues, OidIsValid, VariableStatData::rel, ReleaseVariableStats, root, statistic_proc_security_check(), VariableStatData::statsTuple, TYPECACHE_CMP_PROC_FINFO, and AttStatsSlot::values.
Referenced by scalararraysel().
◆ statistic_proc_security_check()
Definition at line 6120 of file selfuncs.c.
6121{
6122 if (vardata->acl_ok)
6123 return true;
6124
6126 return false;
6127
6129 return true;
6130
6132 (errmsg_internal("not using statistics because function \"%s\" is not leakproof",
6134 return false;
6135}
int errmsg_internal(const char *fmt,...)
#define ereport(elevel,...)
bool get_func_leakproof(Oid funcid)
char * get_func_name(Oid funcid)
References VariableStatData::acl_ok, DEBUG2, ereport, errmsg_internal(), get_func_leakproof(), get_func_name(), and OidIsValid.
Referenced by calc_arraycontsel(), calc_hist_selectivity(), eqjoinsel(), get_variable_range(), histogram_selectivity(), ineq_histogram_selectivity(), mcv_selectivity(), scalararraysel_containment(), and var_eq_const().
◆ var_eq_const()
double var_eq_const | ( | VariableStatData * | vardata, |
---|---|---|---|
Oid | oproid, | ||
Oid | collation, | ||
Datum | constval, | ||
bool | constisnull, | ||
bool | varonleft, | ||
bool | negate | ||
) |
Definition at line 300 of file selfuncs.c.
303{
304 double selec;
305 double nullfrac = 0.0;
306 bool isdefault;
307 Oid opfuncoid;
308
309
310
311
312
313 if (constisnull)
314 return 0.0;
315
316
317
318
319
321 {
323
325 nullfrac = stats->stanullfrac;
326 }
327
328
329
330
331
332
333
334
336 {
337 selec = 1.0 / vardata->rel->tuples;
338 }
342 {
344 bool match = false;
345 int i;
346
347
348
349
350
351
352
353
357 {
360
362
363
364
365
366
367
368
370 NULL, NULL);
371 fcinfo->args[0].isnull = false;
372 fcinfo->args[1].isnull = false;
373
374 if (varonleft)
375 fcinfo->args[1].value = constval;
376 else
377 fcinfo->args[0].value = constval;
378
380 {
382
383 if (varonleft)
384 fcinfo->args[0].value = sslot.values[i];
385 else
386 fcinfo->args[1].value = sslot.values[i];
387 fcinfo->isnull = false;
389 if (!fcinfo->isnull && DatumGetBool(fresult))
390 {
391 match = true;
392 break;
393 }
394 }
395 }
396 else
397 {
398
399 i = 0;
400 }
401
402 if (match)
403 {
404
405
406
407
409 }
410 else
411 {
412
413
414
415
416
417 double sumcommon = 0.0;
418 double otherdistinct;
419
421 sumcommon += sslot.numbers[i];
422 selec = 1.0 - sumcommon - nullfrac;
424
425
426
427
428
429
432 if (otherdistinct > 1)
433 selec /= otherdistinct;
434
435
436
437
438
441 }
442
444 }
445 else
446 {
447
448
449
450
451
453 }
454
455
456 if (negate)
457 selec = 1.0 - selec - nullfrac;
458
459
461
462 return selec;
463}
References ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, CLAMP_PROBABILITY, DatumGetBool(), fmgr_info(), free_attstatsslot(), FunctionCallInvoke, get_attstatsslot(), get_opcode(), get_variable_numdistinct(), GETSTRUCT(), HeapTupleIsValid, i, InitFunctionCallInfoData, InvalidOid, VariableStatData::isunique, LOCAL_FCINFO, AttStatsSlot::nnumbers, AttStatsSlot::numbers, AttStatsSlot::nvalues, VariableStatData::rel, statistic_proc_security_check(), VariableStatData::statsTuple, RelOptInfo::tuples, and AttStatsSlot::values.
Referenced by boolvarsel(), eqsel_internal(), patternsel_common(), and prefix_selectivity().
◆ var_eq_non_const()
Definition at line 471 of file selfuncs.c.
474{
475 double selec;
476 double nullfrac = 0.0;
477 bool isdefault;
478
479
480
481
483 {
485
487 nullfrac = stats->stanullfrac;
488 }
489
490
491
492
493
494
495
496
498 {
499 selec = 1.0 / vardata->rel->tuples;
500 }
502 {
503 double ndistinct;
505
506
507
508
509
510
511
512
513
514
515
516 selec = 1.0 - nullfrac;
518 if (ndistinct > 1)
519 selec /= ndistinct;
520
521
522
523
524
528 {
530 selec = sslot.numbers[0];
532 }
533 }
534 else
535 {
536
537
538
539
540
542 }
543
544
545 if (negate)
546 selec = 1.0 - selec - nullfrac;
547
548
550
551 return selec;
552}
References ATTSTATSSLOT_NUMBERS, CLAMP_PROBABILITY, free_attstatsslot(), get_attstatsslot(), get_variable_numdistinct(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, VariableStatData::isunique, AttStatsSlot::nnumbers, AttStatsSlot::numbers, VariableStatData::rel, VariableStatData::statsTuple, and RelOptInfo::tuples.
Referenced by eqsel_internal().