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 (equal(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;

3612 List *newvarinfos = NIL;

3613 List *relvarinfos = NIL;

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 (OidIsValid(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

2119 for (i = 0; i < 10; i++)

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().

get_index_stats_hook

get_relation_stats_hook