131#include "utils/fmgroids.h"
144#define DEFAULT_PAGE_CPU_MULTIPLIER 50.0
153#ifndef USE_ASSERT_CHECKING
154#define EQJOINSEL_MCV_HASH_THRESHOLD 200
156#define EQJOINSEL_MCV_HASH_THRESHOLD 20
188 Oid hashLeft,
Oid hashRight,
190 double nd1,
double nd2,
191 bool isdefault1,
bool isdefault2,
194 bool have_mcvs1,
bool have_mcvs2,
195 bool *hasmatch1,
bool *hasmatch2,
198 Oid hashLeft,
Oid hashRight,
201 double nd1,
double nd2,
202 bool isdefault1,
bool isdefault2,
205 bool have_mcvs1,
bool have_mcvs2,
206 bool *hasmatch1,
bool *hasmatch2,
210 Oid hashLeft,
Oid hashRight,
213 int nvalues1,
int nvalues2,
214 bool *hasmatch1,
bool *hasmatch2,
215 int *p_nmatches,
double *p_matchprodfreq);
223 double *scaledlobound,
double *scaledhibound);
228 double *scaledlobound,
230 double *scaledhibound);
234 double *scaledlobound,
236 double *scaledhibound);
238 int rangelo,
int rangehi);
240 int rangelo,
int rangehi);
250 Oid sortop,
Oid collation,
254 Oid collation,
int16 typLen,
bool typByVal,
258 Oid sortop,
Oid collation,
268 Datum *endpointDatum);
274#define SH_PREFIX MCVHashTable
275#define SH_ELEMENT_TYPE MCVHashEntry
276#define SH_KEY_TYPE Datum
278#define SH_HASH_KEY(tab,key) hash_mcv(tab, key)
279#define SH_EQUAL(tab,key0,key1) mcvs_equal(tab, key0, key1)
280#define SH_SCOPE static inline
282#define SH_GET_HASH(tab,ent) (ent)->hash
337 &vardata, &other, &varonleft))
347 ((
Const *) other)->constvalue,
348 ((
Const *) other)->constisnull,
366 Datum constval,
bool constisnull,
367 bool varonleft,
bool negate)
370 double nullfrac = 0.0;
390 nullfrac = stats->stanullfrac;
436 fcinfo->args[0].isnull =
false;
437 fcinfo->args[1].isnull =
false;
440 fcinfo->args[1].value = constval;
442 fcinfo->args[0].value = constval;
449 fcinfo->args[0].value = sslot.
values[
i];
451 fcinfo->args[1].value = sslot.
values[
i];
452 fcinfo->isnull =
false;
482 double sumcommon = 0.0;
483 double otherdistinct;
487 selec = 1.0 - sumcommon - nullfrac;
497 if (otherdistinct > 1)
498 selec /= otherdistinct;
522 selec = 1.0 - selec - nullfrac;
538 bool varonleft,
bool negate)
541 double nullfrac = 0.0;
552 nullfrac = stats->stanullfrac;
581 selec = 1.0 - nullfrac;
611 selec = 1.0 - selec - nullfrac;
695 if (block >= vardata->
rel->
pages - 1)
710 block +=
Min(offset / density, 1.0);
717 selec = block / (vardata->
rel->
pages - 0.5);
727 if (iseq == isgt && vardata->
rel->
tuples >= 1.0)
751 mcv_selec =
mcv_selectivity(vardata, &opproc, collation, constval,
true,
759 operator, &opproc, isgt, iseq,
761 constval, consttype);
768 selec = 1.0 - stats->stanullfrac - sumcommon;
770 if (hist_selec >= 0.0)
803 Datum constval,
bool varonleft,
831 fcinfo->args[0].isnull =
false;
832 fcinfo->args[1].isnull =
false;
835 fcinfo->args[1].value = constval;
837 fcinfo->args[0].value = constval;
844 fcinfo->args[0].value = sslot.
values[
i];
846 fcinfo->args[1].value = sslot.
values[
i];
847 fcinfo->isnull =
false;
856 *sumcommonp = sumcommon;
895 Datum constval,
bool varonleft,
896 int min_hist_size,
int n_skip,
904 Assert(min_hist_size > 2 * n_skip);
913 if (sslot.
nvalues >= min_hist_size)
929 fcinfo->args[0].isnull =
false;
930 fcinfo->args[1].isnull =
false;
933 fcinfo->args[1].value = constval;
935 fcinfo->args[0].value = constval;
937 for (
i = n_skip;
i < sslot.
nvalues - n_skip;
i++)
942 fcinfo->args[0].value = sslot.
values[
i];
944 fcinfo->args[1].value = sslot.
values[
i];
945 fcinfo->isnull =
false;
950 result = ((double) nmatch) / ((double) (sslot.
nvalues - 2 * n_skip));
986 double default_selectivity)
998 &vardata, &other, &varonleft))
999 return default_selectivity;
1006 ((
Const *) other)->constisnull)
1015 Datum constval = ((
Const *) other)->constvalue;
1028 constval, varonleft,
1038 constval, varonleft,
1043 selec = default_selectivity;
1045 else if (hist_size < 100)
1052 double hist_weight = hist_size / 100.0;
1054 selec = selec * hist_weight +
1055 default_selectivity * (1.0 - hist_weight);
1061 else if (selec > 0.9999)
1075 selec *= 1.0 - nullfrac - mcvsum;
1081 selec = default_selectivity;
1113 Oid opoid,
FmgrInfo *opproc,
bool isgt,
bool iseq,
1165 bool have_end =
false;
1181 while (lobound < hibound)
1183 int probe = (lobound + hibound) / 2;
1191 if (probe == 0 && sslot.
nvalues > 2)
1213 lobound = probe + 1;
1230 else if (lobound >= sslot.
nvalues)
1241 double eq_selec = 0;
1263 if (
i == 1 || isgt == iseq)
1265 double otherdistinct;
1283 if (otherdistinct > 1)
1284 eq_selec = 1.0 / otherdistinct;
1303 else if (
val <= low)
1305 else if (
val >= high)
1309 binfrac = (
val - low) / (high - low);
1317 if (isnan(binfrac) ||
1318 binfrac < 0.0 || binfrac > 1.0)
1340 histfrac = (double) (
i - 1) + binfrac;
1341 histfrac /= (double) (sslot.
nvalues - 1);
1376 histfrac += eq_selec * (1.0 - binfrac);
1384 histfrac -= eq_selec;
1391 hist_selec = isgt ? (1.0 - histfrac) : histfrac;
1406 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1408 if (hist_selec < cutoff)
1409 hist_selec = cutoff;
1410 else if (hist_selec > 1.0 - cutoff)
1411 hist_selec = 1.0 - cutoff;
1428 fcinfo->args[0].isnull =
false;
1429 fcinfo->args[1].isnull =
false;
1430 fcinfo->args[1].value = constval;
1435 fcinfo->args[0].value = sslot.
values[
i];
1436 fcinfo->isnull =
false;
1441 hist_selec = ((double) nmatch) / ((double) sslot.
nvalues);
1450 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1452 if (hist_selec < cutoff)
1453 hist_selec = cutoff;
1454 else if (hist_selec > 1.0 - cutoff)
1455 hist_selec = 1.0 - cutoff;
1489 &vardata, &other, &varonleft))
1505 if (((
Const *) other)->constisnull)
1510 constval = ((
Const *) other)->constvalue;
1511 consttype = ((
Const *) other)->consttype;
1530 &vardata, constval, consttype);
1636 freq_null = stats->stanullfrac;
1652 freq_true = 1.0 - sslot.
numbers[0] - freq_null;
1658 freq_false = 1.0 - freq_true - freq_null;
1660 switch (booltesttype)
1668 selec = 1.0 - freq_null;
1676 selec = 1.0 - freq_true;
1684 selec = 1.0 - freq_false;
1687 elog(
ERROR,
"unrecognized booltesttype: %d",
1688 (
int) booltesttype);
1702 switch (booltesttype)
1710 selec = 1.0 - freq_null;
1715 selec = (1.0 - freq_null) / 2.0;
1721 selec = (freq_null + 1.0) / 2.0;
1724 elog(
ERROR,
"unrecognized booltesttype: %d",
1725 (
int) booltesttype);
1739 switch (booltesttype)
1760 elog(
ERROR,
"unrecognized booltesttype: %d",
1761 (
int) booltesttype);
1793 freq_null = stats->stanullfrac;
1795 switch (nulltesttype)
1810 selec = 1.0 - freq_null;
1813 elog(
ERROR,
"unrecognized nulltesttype: %d",
1814 (
int) nulltesttype);
1819 ((
Var *) vardata.
var)->varattno < 0)
1825 selec = (nulltesttype ==
IS_NULL) ? 0.0 : 1.0;
1832 switch (nulltesttype)
1841 elog(
ERROR,
"unrecognized nulltesttype: %d",
1842 (
int) nulltesttype);
1899 bool is_join_clause,
1905 bool useOr = clause->
useOr;
1906 bool isEquality =
false;
1907 bool isInequality =
false;
1910 Oid nominal_element_type;
1911 Oid nominal_element_collation;
1944 if (
operator == typentry->
eq_opr)
1947 isInequality =
true;
1956 if ((isEquality || isInequality) && !is_join_clause)
1959 nominal_element_type,
1960 isEquality, useOr, varRelid);
1985 if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
1987 else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
1988 isInequality =
true;
2002 if (rightop &&
IsA(rightop,
Const))
2004 Datum arraydatum = ((
Const *) rightop)->constvalue;
2005 bool arrayisnull = ((
Const *) rightop)->constisnull;
2019 &elmlen, &elmbyval, &elmalign);
2022 elmlen, elmbyval, elmalign,
2023 &elem_values, &elem_nulls, &num_elems);
2039 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2041 for (
i = 0;
i < num_elems;
i++)
2049 nominal_element_collation,
2056 clause->inputcollid,
2064 clause->inputcollid,
2080 s1disjoint +=
s2 - 1.0;
2085 if ((useOr ? isEquality : isInequality) &&
2086 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2098 &elmlen, &elmbyval);
2107 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2109 foreach(l, arrayexpr->elements)
2123 clause->inputcollid,
2131 clause->inputcollid,
2147 s1disjoint +=
s2 - 1.0;
2152 if ((useOr ? isEquality : isInequality) &&
2153 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2169 dummyexpr->
typeId = nominal_element_type;
2170 dummyexpr->typeMod = -1;
2171 dummyexpr->collation = clause->inputcollid;
2175 clause->inputcollid,
2183 clause->inputcollid,
2188 s1 = useOr ? 0.0 : 1.0;
2195 for (
i = 0;
i < 10;
i++)
2225 if (arrayexpr &&
IsA(arrayexpr,
Const))
2227 Datum arraydatum = ((
Const *) arrayexpr)->constvalue;
2228 bool arrayisnull = ((
Const *) arrayexpr)->constisnull;
2241 else if (arrayexpr &&
root)
2294 bool is_join_clause;
2310 is_join_clause =
false;
2312 else if (sjinfo == NULL)
2318 is_join_clause =
false;
2380 bool have_mcvs1 =
false;
2381 bool have_mcvs2 =
false;
2382 bool *hasmatch1 = NULL;
2383 bool *hasmatch2 = NULL;
2386 bool join_is_reversed;
2390 &vardata1, &vardata2, &join_is_reversed);
2397 memset(&sslot1, 0,
sizeof(sslot1));
2398 memset(&sslot2, 0,
sizeof(sslot2));
2417 if (get_mcv_stats &&
2428 if (get_mcv_stats &&
2436 if (have_mcvs1 && have_mcvs2)
2450 memset(&eqproc, 0,
sizeof(eqproc));
2454 hashLeft, hashRight,
2455 &vardata1, &vardata2,
2457 isdefault1, isdefault2,
2460 have_mcvs1, have_mcvs2,
2461 hasmatch1, hasmatch2,
2469 selec = selec_inner;
2482 if (!join_is_reversed)
2484 hashLeft, hashRight,
2486 &vardata1, &vardata2,
2488 isdefault1, isdefault2,
2491 have_mcvs1, have_mcvs2,
2492 hasmatch1, hasmatch2,
2497 hashLeft, hashRight,
2499 &vardata2, &vardata1,
2501 isdefault2, isdefault1,
2504 have_mcvs2, have_mcvs1,
2505 hasmatch2, hasmatch1,
2519 selec =
Min(selec, inner_rel->
rows * selec_inner);
2523 elog(
ERROR,
"unrecognized join type: %d",
2557 Oid hashLeft,
Oid hashRight,
2559 double nd1,
double nd2,
2560 bool isdefault1,
bool isdefault2,
2563 bool have_mcvs1,
bool have_mcvs2,
2564 bool *hasmatch1,
bool *hasmatch2,
2569 if (have_mcvs1 && have_mcvs2)
2583 double nullfrac1 = stats1->stanullfrac;
2584 double nullfrac2 = stats2->stanullfrac;
2585 double matchprodfreq,
2599 hashLeft, hashRight,
2603 hasmatch1, hasmatch2,
2604 p_nmatches, &matchprodfreq);
2605 nmatches = *p_nmatches;
2609 matchfreq1 = unmatchfreq1 = 0.0;
2615 unmatchfreq1 += sslot1->
numbers[
i];
2619 matchfreq2 = unmatchfreq2 = 0.0;
2625 unmatchfreq2 += sslot2->
numbers[
i];
2634 otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
2635 otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
2647 totalsel1 = matchprodfreq;
2649 totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->
nvalues);
2651 totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
2654 totalsel2 = matchprodfreq;
2656 totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->
nvalues);
2658 totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
2667 selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
2691 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2692 double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
2694 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
2716 Oid hashLeft,
Oid hashRight,
2717 bool op_is_reversed,
2719 double nd1,
double nd2,
2720 bool isdefault1,
bool isdefault2,
2723 bool have_mcvs1,
bool have_mcvs2,
2724 bool *hasmatch1,
bool *hasmatch2,
2751 if (nd2 >= vardata2->
rel->
rows)
2757 if (nd2 >= inner_rel->
rows)
2759 nd2 = inner_rel->
rows;
2763 if (have_mcvs1 && have_mcvs2)
2773 double nullfrac1 = stats1->stanullfrac;
2774 double matchprodfreq,
2789 clamped_nvalues2 =
Min(sslot2->
nvalues, nd2);
2801 if (clamped_nvalues2 != sslot2->
nvalues)
2804 memset(hasmatch1, 0, sslot1->
nvalues *
sizeof(
bool));
2805 memset(hasmatch2, 0, clamped_nvalues2 *
sizeof(
bool));
2808 hashLeft, hashRight,
2811 sslot1->
nvalues, clamped_nvalues2,
2812 hasmatch1, hasmatch2,
2813 p_nmatches, &matchprodfreq);
2815 nmatches = *p_nmatches;
2841 if (!isdefault1 && !isdefault2)
2845 if (nd1 <= nd2 || nd2 < 0)
2846 uncertainfrac = 1.0;
2848 uncertainfrac = nd2 / nd1;
2851 uncertainfrac = 0.5;
2852 uncertain = 1.0 - matchfreq1 - nullfrac1;
2854 selec = matchfreq1 + uncertainfrac * uncertain;
2862 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2864 if (!isdefault1 && !isdefault2)
2866 if (nd1 <= nd2 || nd2 < 0)
2867 selec = 1.0 - nullfrac1;
2869 selec = (nd2 / nd1) * (1.0 - nullfrac1);
2872 selec = 0.5 * (1.0 - nullfrac1);
2907 Oid hashLeft,
Oid hashRight,
2908 bool op_is_reversed,
2910 int nvalues1,
int nvalues2,
2911 bool *hasmatch1,
bool *hasmatch2,
2912 int *p_nmatches,
double *p_matchprodfreq)
2915 double matchprodfreq = 0.0;
2925 fcinfo->args[0].isnull =
false;
2926 fcinfo->args[1].isnull =
false;
2937 bool *hasMatchProbe;
2945 statsProbe = sslot1;
2947 hasMatchProbe = hasmatch1;
2948 hasMatchHash = hasmatch2;
2949 nvaluesProbe = nvalues1;
2950 nvaluesHash = nvalues2;
2955 op_is_reversed = !op_is_reversed;
2956 statsProbe = sslot2;
2958 hasMatchProbe = hasmatch2;
2959 hasMatchHash = hasmatch1;
2960 nvaluesProbe = nvalues2;
2961 nvaluesHash = nvalues1;
2968 fmgr_info(op_is_reversed ? hashLeft : hashRight, &hash_proc);
2971 hash_fcinfo->args[0].isnull =
false;
2985 for (
int i = 0;
i < nvaluesHash;
i++)
3012 if (hashLeft != hashRight)
3014 fmgr_info(op_is_reversed ? hashRight : hashLeft, &hash_proc);
3018 hash_fcinfo->args[0].isnull =
false;
3022 for (
int i = 0;
i < nvaluesProbe;
i++)
3028 if (entry != NULL && !hasMatchHash[entry->
index])
3030 hasMatchHash[entry->
index] = hasMatchProbe[
i] =
true;
3036 MCVHashTable_destroy(hashTable);
3056 for (
int i = 0;
i < nvalues1;
i++)
3058 fcinfo->args[index1].value = sslot1->
values[
i];
3060 for (
int j = 0;
j < nvalues2;
j++)
3066 fcinfo->args[index2].value = sslot2->
values[
j];
3067 fcinfo->isnull =
false;
3071 hasmatch1[
i] = hasmatch2[
j] =
true;
3080 *p_nmatches = nmatches;
3081 *p_matchprodfreq = matchprodfreq;
3095 fcinfo->isnull =
false;
3191 result = 1.0 - nullfrac;
3217 result = 1.0 - result;
3318 *leftstart = *rightstart = 0.0;
3319 *leftend = *rightend = 1.0;
3324 opno = ((
OpExpr *) clause)->opno;
3325 collation = ((
OpExpr *) clause)->inputcollid;
3357 if (op_lefttype == op_righttype)
3361 op_lefttype, op_righttype,
3364 op_lefttype, op_righttype,
3376 op_lefttype, op_righttype,
3379 op_lefttype, op_righttype,
3382 op_lefttype, op_lefttype,
3385 op_righttype, op_righttype,
3390 op_righttype, op_lefttype,
3393 op_righttype, op_lefttype,
3403 if (op_lefttype == op_righttype)
3407 op_lefttype, op_righttype,
3410 op_lefttype, op_righttype,
3415 op_lefttype, op_lefttype,
3424 op_lefttype, op_righttype,
3427 op_lefttype, op_righttype,
3430 op_lefttype, op_lefttype,
3433 op_righttype, op_righttype,
3436 op_lefttype, op_lefttype,
3439 op_righttype, op_righttype,
3442 op_righttype, op_lefttype,
3445 op_righttype, op_lefttype,
3467 &leftmin, &leftmax))
3470 &rightmin, &rightmax))
3477 &leftmax, &leftmin))
3480 &rightmax, &rightmin))
3490 rightmax, op_righttype);
3496 leftmax, op_lefttype);
3506 if (*leftend > *rightend)
3508 else if (*leftend < *rightend)
3511 *leftend = *rightend = 1.0;
3520 rightmin, op_righttype);
3526 leftmin, op_lefttype);
3528 *rightstart = selec;
3536 if (*leftstart < *rightstart)
3538 else if (*leftstart > *rightstart)
3541 *leftstart = *rightstart = 0.0;
3556 *leftstart += stats->stanullfrac;
3558 *leftend += stats->stanullfrac;
3564 *rightstart += stats->stanullfrac;
3566 *rightend += stats->stanullfrac;
3572 if (*leftstart >= *leftend)
3577 if (*rightstart >= *rightend)
3657 foreach(lc, varinfos)
3670 if (vardata->
rel != varinfo->
rel &&
3689 varinfo->
rel = vardata->
rel;
3692 varinfos =
lappend(varinfos, varinfo);
3772 double srf_multiplier = 1.0;
3778 if (estinfo != NULL)
3794 if (groupExprs ==
NIL || (pgset && *pgset ==
NIL))
3807 foreach(l, groupExprs)
3810 double this_srf_multiplier;
3831 if (srf_multiplier < this_srf_multiplier)
3832 srf_multiplier = this_srf_multiplier;
3835 if (
exprType(groupexpr) == BOOLOID)
3858 groupexpr, &vardata);
3881 if (varshere ==
NIL)
3891 foreach(l2, varshere)
3905 if (varinfos ==
NIL)
3908 numdistinct *= srf_multiplier;
3910 numdistinct = ceil(numdistinct);
3912 if (numdistinct > input_rows)
3913 numdistinct = input_rows;
3914 if (numdistinct < 1.0)
3931 double reldistinct = 1;
3932 double relmaxndistinct = reldistinct;
3933 int relvarcount = 0;
3941 relvarinfos =
lappend(relvarinfos, varinfo1);
3946 if (varinfo2->
rel == varinfo1->
rel)
3949 relvarinfos =
lappend(relvarinfos, varinfo2);
3954 newvarinfos =
lappend(newvarinfos, varinfo2);
3977 reldistinct *= mvndistinct;
3978 if (relmaxndistinct < mvndistinct)
3979 relmaxndistinct = mvndistinct;
3984 foreach(l, relvarinfos)
3989 if (relmaxndistinct < varinfo2->ndistinct)
3997 if (estinfo != NULL && varinfo2->
isdefault)
4019 double clamp = rel->
tuples;
4021 if (relvarcount > 1)
4024 if (clamp < relmaxndistinct)
4026 clamp = relmaxndistinct;
4032 if (reldistinct > clamp)
4033 reldistinct = clamp;
4040 if (reldistinct > 0 && rel->
rows < rel->
tuples)
4078 rel->
tuples / reldistinct));
4085 numdistinct *= reldistinct;
4088 varinfos = newvarinfos;
4089 }
while (varinfos !=
NIL);
4092 numdistinct *= srf_multiplier;
4095 numdistinct = ceil(numdistinct);
4098 if (numdistinct > input_rows)
4099 numdistinct = input_rows;
4100 if (numdistinct < 1.0)
4143 while (clauses !=
NIL)
4150 List *origin_varinfos;
4151 int group_relid = -1;
4162 foreach(lc, clauses)
4174 relids = rinfo->outer_is_left ?
4175 rinfo->right_relids : rinfo->left_relids;
4176 expr = rinfo->outer_is_left ?
4180 root->simple_rel_array[relid]->statlist !=
NIL)
4182 bool is_duplicate =
false;
4188 if (group_relid < 0)
4192 if (!rte || (rte->relkind != RELKIND_RELATION &&
4193 rte->relkind != RELKIND_MATVIEW &&
4194 rte->relkind != RELKIND_FOREIGN_TABLE &&
4195 rte->relkind != RELKIND_PARTITIONED_TABLE))
4198 otherclauses =
lappend(otherclauses, rinfo);
4203 group_relid = relid;
4204 group_rel =
root->simple_rel_array[relid];
4206 else if (group_relid != relid)
4242 foreach(lc1, varinfos)
4249 is_duplicate =
true;
4268 varinfo->
var = expr;
4269 varinfo->
rel =
root->simple_rel_array[relid];
4270 varinfos =
lappend(varinfos, varinfo);
4276 origin_rinfos =
lappend(origin_rinfos, rinfo);
4281 otherclauses =
lappend(otherclauses, rinfo);
4293 otherclauses =
list_concat(otherclauses, origin_rinfos);
4299 Assert(group_rel != NULL);
4302 origin_varinfos = varinfos;
4318 if (ndistinct < mvndistinct)
4319 ndistinct = mvndistinct;
4320 Assert(ndistinct >= 1.0);
4326 forboth(lc1, origin_varinfos, lc2, origin_rinfos)
4339 *innerbucketsize = 1.0 / ndistinct;
4340 return otherclauses;
4439 stanullfrac = stats->stanullfrac;
4445 avgfreq = (1.0 - stanullfrac) / ndistinct;
4466 if (ndistinct > nbuckets)
4467 estfract = 1.0 / nbuckets;
4469 estfract = 1.0 / ndistinct;
4474 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
4475 estfract *= *mcv_freq / avgfreq;
4482 if (estfract < 1.0e-6)
4484 else if (estfract > 1.0)
4512 path->pathtarget->width,
4521 return hashentrysize * dNumGroups;
4548 List **varinfos,
double *ndistinct)
4569 int nshared_vars = 0;
4570 int nshared_exprs = 0;
4573 if (info->
kind != STATS_EXT_NDISTINCT)
4585 foreach(lc2, *varinfos)
4613 foreach(lc3, info->
exprs)
4631 if (nshared_vars + nshared_exprs < 2)
4642 if ((nshared_exprs > nmatches_exprs) ||
4643 (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
4646 nmatches_vars = nshared_vars;
4647 nmatches_exprs = nshared_exprs;
4648 matched_info = info;
4656 Assert(nmatches_vars + nmatches_exprs > 1);
4678 if (matched_info->
exprs)
4684 foreach(lc2, *varinfos)
4732 foreach(lc3, matched_info->
exprs)
4799 elog(
ERROR,
"corrupt MVNDistinct entry");
4802 foreach(lc, *varinfos)
4824 newlist =
lappend(newlist, varinfo);
4833 newlist =
lappend(newlist, varinfo);
4849 foreach(lc3, matched_info->
exprs)
4864 newlist =
lappend(newlist, varinfo);
4867 *varinfos = newlist;
4907 double *scaledlobound,
double *scaledhibound)
4909 bool failure =
false;
4943 case REGPROCEDUREOID:
4945 case REGOPERATOROID:
4948 case REGCOLLATIONOID:
4950 case REGDICTIONARYOID:
4952 case REGNAMESPACEOID:
4953 case REGDATABASEOID:
4987 lostr, scaledlobound,
4988 histr, scaledhibound);
5001 if (boundstypid != BYTEAOID)
5004 lobound, scaledlobound,
5005 hibound, scaledhibound);
5013 case TIMESTAMPTZOID:
5042 *scaledvalue = *scaledlobound = *scaledhibound = 0;
5076 case REGPROCEDUREOID:
5078 case REGOPERATOROID:
5081 case REGCOLLATIONOID:
5083 case REGDICTIONARYOID:
5085 case REGNAMESPACEOID:
5086 case REGDATABASEOID:
5117 double *scaledvalue,
5119 double *scaledlobound,
5121 double *scaledhibound)
5127 rangelo = rangehi = (
unsigned char) hibound[0];
5128 for (sptr = lobound; *sptr; sptr++)
5130 if (rangelo > (
unsigned char) *sptr)
5131 rangelo = (
unsigned char) *sptr;
5132 if (rangehi < (
unsigned char) *sptr)
5133 rangehi = (
unsigned char) *sptr;
5135 for (sptr = hibound; *sptr; sptr++)
5137 if (rangelo > (
unsigned char) *sptr)
5138 rangelo = (
unsigned char) *sptr;
5139 if (rangehi < (
unsigned char) *sptr)
5140 rangehi = (
unsigned char) *sptr;
5143 if (rangelo <= 'Z' && rangehi >=
'A')
5151 if (rangelo <= 'z' && rangehi >=
'a')
5159 if (rangelo <= '9' && rangehi >=
'0')
5171 if (rangehi - rangelo < 9)
5182 if (*lobound != *hibound || *lobound != *
value)
5184 lobound++, hibound++,
value++;
5198 int slen = strlen(
value);
5219 base = rangehi - rangelo + 1;
5224 int ch = (
unsigned char) *
value++;
5228 else if (ch > rangehi)
5230 num += ((double) (ch - rangelo)) / denom;
5305 if (xfrmlen == INT_MAX)
5308 xfrmstr = (
char *)
palloc(xfrmlen + 1);
5315 Assert(xfrmlen2 <= xfrmlen);
5336 double *scaledvalue,
5338 double *scaledlobound,
5340 double *scaledhibound)
5352 unsigned char *valstr = (
unsigned char *)
VARDATA_ANY(valuep);
5353 unsigned char *lostr = (
unsigned char *)
VARDATA_ANY(loboundp);
5354 unsigned char *histr = (
unsigned char *)
VARDATA_ANY(hiboundp);
5365 minlen =
Min(
Min(valuelen, loboundlen), hiboundlen);
5366 for (
i = 0;
i < minlen;
i++)
5368 if (*lostr != *histr || *lostr != *valstr)
5370 lostr++, histr++, valstr++;
5371 loboundlen--, hiboundlen--, valuelen--;
5384 int rangelo,
int rangehi)
5401 base = rangehi - rangelo + 1;
5404 while (valuelen-- > 0)
5410 else if (ch > rangehi)
5412 num += ((double) (ch - rangelo)) / denom;
5432 case TIMESTAMPTZOID:
5459 return (
double) (timetz->
time + (timetz->
zone * 1000000.0));
5517 if (vardata->
rel && rdata.
rel == NULL)
5525 if (vardata->
rel == NULL && rdata.
rel)
5554 bool *join_is_reversed)
5560 elog(
ERROR,
"join operator should take two arguments");
5568 if (vardata1->
rel &&
5570 *join_is_reversed =
true;
5571 else if (vardata2->
rel &&
5573 *join_is_reversed =
true;
5575 *join_is_reversed =
false;
5644 if (
IsA(basenode,
Var) &&
5645 (varRelid == 0 || varRelid == ((
Var *) basenode)->varno))
5647 Var *var = (
Var *) basenode;
5650 vardata->
var = basenode;
5652 vardata->
atttype = var->vartype;
5683 if (varRelid == 0 || varRelid == relid)
5686 vardata->
rel = onerel;
5713 vardata->
var = node;
5750 if (indexpr_item == NULL)
5753 for (pos = 0; pos <
index->ncolumns; pos++)
5755 if (
index->indexkeys[pos] == 0)
5759 if (indexpr_item == NULL)
5760 elog(
ERROR,
"too few entries in indexprs list");
5764 if (
equal(node, indexkey))
5770 if (
index->unique &&
5771 index->nkeycolumns == 1 &&
5797 elog(
ERROR,
"no function provided to release variable stats with");
5846 indexpr_item =
lnext(
index->indexprs, indexpr_item);
5874 if (info->
kind != STATS_EXT_EXPRESSIONS)
5882 foreach(expr_item, info->
exprs)
5893 if (
equal(node, expr))
5963 elog(
ERROR,
"no function provided to release variable stats with");
6054 while (levelsup-- > 0)
6056 cteroot = cteroot->parent_root;
6086 if (subroot == NULL)
6097 subquery = subroot->
parse;
6118 if (ste == NULL || ste->resjunk)
6119 elog(
ERROR,
"subquery %s does not have attribute %d",
6120 rte->eref->aliasname, var->
varattno);
6161 if (rte->security_barrier)
6165 if (var &&
IsA(var,
Var) &&
6264 if (
root->append_rel_array != NULL)
6268 appinfo =
root->append_rel_array[varno];
6304 parent_attno = appinfo->parent_colnos[attno - 1];
6305 if (parent_attno == 0)
6317 parent_attno = attno;
6323 parent_attno = appinfo->parent_colnos[attno - 1];
6324 if (parent_attno == 0)
6335 varattnos = parent_varattnos;
6336 appinfo =
root->append_rel_array[varno];
6348 if (rte->securityQuals !=
NIL)
6366 if (varattnos == NULL)
6424 if (
index->indexkeys[indexcol] != 0)
6432 colnum =
index->indexkeys[indexcol];
6444 elog(
ERROR,
"no function provided to release variable stats with");
6458 relid =
index->indexoid;
6459 colnum = indexcol + 1;
6470 elog(
ERROR,
"no function provided to release variable stats with");
6504 (
errmsg_internal(
"not using statistics because function \"%s\" is not leakproof",
6524 double stanullfrac = 0.0;
6541 stadistinct = stats->stadistinct;
6542 stanullfrac = stats->stanullfrac;
6544 else if (vardata->
vartype == BOOLOID)
6573 switch (((
Var *) vardata->
var)->varattno)
6602 stadistinct = -1.0 * (1.0 - stanullfrac);
6607 if (stadistinct > 0.0)
6613 if (vardata->
rel == NULL)
6628 if (stadistinct < 0.0)
6655 Oid sortop,
Oid collation,
6660 bool have_data =
false;
6705 STATISTIC_KIND_HISTOGRAM, sortop,
6729 collation, typLen, typByVal,
6730 &tmin, &tmax, &have_data);
6747 bool use_mcvs = have_data;
6751 double sumcommon = 0.0;
6758 if (sumcommon + nullfrac > 0.99999)
6764 collation, typLen, typByVal,
6765 &tmin, &tmax, &have_data);
6782 Oid collation,
int16 typLen,
bool typByVal,
6787 bool have_data = *p_have_data;
6788 bool found_tmin =
false;
6789 bool found_tmax =
false;
6792 if (opproc->
fn_oid != opfuncoid)
6800 tmin = tmax = sslot->
values[
i];
6801 found_tmin = found_tmax =
true;
6802 *p_have_data = have_data =
true;
6825 *min =
datumCopy(tmin, typByVal, typLen);
6827 *max =
datumCopy(tmax, typByVal, typLen);
6845 Oid sortop,
Oid collation,
6848 bool have_data =
false;
6857 rte =
root->simple_rte_array[rel->
relid];
6861 if (rte->relkind == RELKIND_PARTITIONED_TABLE)
6872 if (
index->sortopfamily == NULL)
6886 if (
index->hypothetical)
6893 if (!
index->canreturn[0])
6900 if (collation !=
index->indexcollations[0])
6908 if (
index->reverse_sort[0])
6914 if (
index->reverse_sort[0])
6940 "get_actual_variable_range workspace",
6985 if (max && have_data)
7041 Datum *endpointDatum)
7043 bool have_data =
false;
7048 int n_visited_heap_pages = 0;
7102 &SnapshotNonVacuumable, NULL,
7130#define VISITED_PAGES_LIMIT 100
7132 if (block != last_heap_block)
7134 last_heap_block = block;
7135 n_visited_heap_pages++;
7157 elog(
ERROR,
"no data returned for index-only scan");
7172 elog(
ERROR,
"found unexpected null value in index \"%s\"",
7213 elog(
ERROR,
"could not find RelOptInfo for given relids");
7235 foreach(lc, indexclauses)
7244 result =
lappend(result, rinfo);
7262 Cost qual_arg_cost = 0;
7265 foreach(lc, indexquals)
7268 Node *other_operand;
7298 other_operand = NULL;
7302 elog(
ERROR,
"unsupported indexqual type: %d",
7304 other_operand = NULL;
7310 return qual_arg_cost;
7322 Cost indexStartupCost;
7323 Cost indexTotalCost;
7325 double indexCorrelation;
7326 double numIndexPages;
7327 double numIndexTuples;
7328 double spc_random_page_cost;
7329 double num_sa_scans;
7330 double num_outer_scans;
7332 double qual_op_cost;
7333 double qual_arg_cost;
7334 List *selectivityQuals;
7350 if (num_sa_scans < 1)
7353 foreach(l, indexQuals)
7363 num_sa_scans *= alength;
7380 if (numIndexTuples <= 0.0)
7382 numIndexTuples = indexSelectivity *
index->rel->tuples;
7391 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7399 if (numIndexTuples >
index->tuples)
7400 numIndexTuples =
index->tuples;
7401 if (numIndexTuples < 1.0)
7402 numIndexTuples = 1.0;
7417 numIndexPages = ceil(numIndexTuples *
index->pages /
index->tuples);
7419 numIndexPages = 1.0;
7423 &spc_random_page_cost,
7443 num_outer_scans = loop_count;
7444 num_scans = num_sa_scans * num_outer_scans;
7448 double pages_fetched;
7451 pages_fetched = numIndexPages * num_scans;
7456 (
double)
index->pages,
7464 indexTotalCost = (pages_fetched * spc_random_page_cost)
7473 indexTotalCost = numIndexPages * spc_random_page_cost;
7495 indexStartupCost = qual_arg_cost;
7496 indexTotalCost += qual_arg_cost;
7502 indexCorrelation = 0.0;
7545 foreach(lc,
index->indpred)
7551 predExtraQuals =
list_concat(predExtraQuals, oneQual);
7572 double indexCorrelation = 0;
7577 index->opcintype[0],
7578 index->opcintype[0],
7582 STATISTIC_KIND_CORRELATION, sortop,
7585 double varCorrelation;
7588 varCorrelation = sslot.
numbers[0];
7590 if (
index->reverse_sort[0])
7591 varCorrelation = -varCorrelation;
7593 if (
index->nkeycolumns > 1)
7594 indexCorrelation = varCorrelation * 0.75;
7596 indexCorrelation = varCorrelation;
7601 return indexCorrelation;
7606 Cost *indexStartupCost,
Cost *indexTotalCost,
7607 Selectivity *indexSelectivity,
double *indexCorrelation,
7613 double numIndexTuples;
7615 List *indexBoundQuals;
7616 List *indexSkipQuals;
7619 bool found_row_compare;
7621 bool found_is_null_op;
7622 bool have_correlation =
false;
7623 double num_sa_scans;
7624 double correlation = 0.0;
7647 indexBoundQuals =
NIL;
7648 indexSkipQuals =
NIL;
7651 found_row_compare =
false;
7652 found_array =
false;
7653 found_is_null_op =
false;
7660 if (indexcol < iclause->indexcol)
7662 double num_sa_scans_prev_cols = num_sa_scans;
7688 if (found_row_compare)
7703 indexSkipQuals =
NIL;
7707 while (indexcol < iclause->indexcol)
7710 bool isdefault =
true;
7730 have_correlation =
true;
7741 num_sa_scans = num_sa_scans_prev_cols;
7748 if (indexSkipQuals !=
NIL)
7750 List *partialSkipQuals;
7775 num_sa_scans = num_sa_scans_prev_cols;
7780 ndistinct = rint(ndistinct * ndistinctfrac);
7781 ndistinct =
Max(ndistinct, 1);
7802 if (indexSkipQuals ==
NIL)
7813 num_sa_scans *= ndistinct;
7832 if (
index->pages < num_sa_scans)
7834 num_sa_scans = num_sa_scans_prev_cols;
7839 indexSkipQuals =
NIL;
7869 clause_op = op->
opno;
7876 found_row_compare =
true;
7884 clause_op = saop->
opno;
7888 num_sa_scans *= alength;
7896 found_is_null_op =
true;
7902 elog(
ERROR,
"unsupported indexqual type: %d",
7909 index->opfamily[indexcol]);
7910 Assert(op_strategy != 0);
7915 indexBoundQuals =
lappend(indexBoundQuals, rinfo);
7922 if (!eqQualHere && !found_row_compare &&
7923 indexcol < index->nkeycolumns - 1)
7924 indexSkipQuals =
lappend(indexSkipQuals, rinfo);
7934 if (
index->unique &&
7935 indexcol ==
index->nkeycolumns - 1 &&
7939 numIndexTuples = 1.0;
7942 List *selectivityQuals;
7956 numIndexTuples = btreeSelectivity *
index->rel->tuples;
7981 num_sa_scans =
Min(num_sa_scans, ceil(
index->pages * 0.3333333));
7982 num_sa_scans =
Max(num_sa_scans, 1);
8003 numIndexTuples = rint(numIndexTuples / num_sa_scans);
8025 if (
index->tuples > 1)
8047 if (!have_correlation)
8069 Cost *indexStartupCost,
Cost *indexTotalCost,
8070 Selectivity *indexSelectivity,
double *indexCorrelation,
8111 Cost *indexStartupCost,
Cost *indexTotalCost,
8112 Selectivity *indexSelectivity,
double *indexCorrelation,
8130 if (
index->tree_height < 0)
8132 if (
index->pages > 1)
8133 index->tree_height = (int) (log(
index->pages) / log(100.0));
8135 index->tree_height = 0;
8143 if (
index->tuples > 1)
8166 Cost *indexStartupCost,
Cost *indexTotalCost,
8167 Selectivity *indexSelectivity,
double *indexCorrelation,
8185 if (
index->tree_height < 0)
8187 if (
index->pages > 1)
8188 index->tree_height = (int) (log(
index->pages) / log(100.0));
8190 index->tree_height = 0;
8198 if (
index->tuples > 1)
8251 bool *partial_matches = NULL;
8253 bool *nullFlags = NULL;
8257 Assert(indexcol < index->nkeycolumns);
8266 &strategy_op, &lefttype, &righttype);
8274 index->opcintype[indexcol],
8275 index->opcintype[indexcol],
8281 elog(
ERROR,
"missing support function %d for attribute %d of index \"%s\"",
8290 collation =
index->indexcollations[indexcol];
8292 collation = DEFAULT_COLLATION_OID;
8314 for (
i = 0;
i < nentries;
i++)
8320 if (partial_matches && partial_matches[
i])
8382 if (((
Const *) operand)->constisnull)
8387 ((
Const *) operand)->constvalue,
8408 double numIndexEntries,
8421 int numPossible = 0;
8447 if (((
Const *) rightop)->constisnull)
8453 &elmlen, &elmbyval, &elmalign);
8456 elmlen, elmbyval, elmalign,
8457 &elemValues, &elemNulls, &numElems);
8459 memset(&arraycounts, 0,
sizeof(arraycounts));
8461 for (
i = 0;
i < numElems;
i++)
8470 memset(&elemcounts, 0,
sizeof(elemcounts));
8496 if (numPossible == 0)
8521 Cost *indexStartupCost,
Cost *indexTotalCost,
8522 Selectivity *indexSelectivity,
double *indexCorrelation,
8527 List *selectivityQuals;
8528 double numPages =
index->pages,
8529 numTuples =
index->tuples;
8530 double numEntryPages,
8537 double partialScale;
8538 double entryPagesFetched,
8540 dataPagesFetchedBySel;
8541 double qual_op_cost,
8543 spc_random_page_cost,
8555 if (!
index->hypothetical)
8564 memset(&ginStats, 0,
sizeof(ginStats));
8581 numPendingPages = 0;
8583 if (numPages > 0 && ginStats.
nTotalPages <= numPages &&
8598 numEntryPages =
Min(numEntryPages, numPages - numPendingPages);
8599 numDataPages =
Min(numDataPages,
8600 numPages - numPendingPages - numEntryPages);
8617 numPages =
Max(numPages, 10);
8618 numEntryPages = floor((numPages - numPendingPages) * 0.90);
8619 numDataPages = numPages - numPendingPages - numEntryPages;
8620 numEntries = floor(numEntryPages * 100);
8642 &spc_random_page_cost,
8648 *indexCorrelation = 0.0;
8653 memset(&counts, 0,
sizeof(counts));
8655 matchPossible =
true;
8691 elog(
ERROR,
"unsupported GIN indexqual type: %d",
8700 *indexStartupCost = 0;
8701 *indexTotalCost = 0;
8702 *indexSelectivity = 0;
8712 fullIndexScan =
false;
8713 for (
i = 0;
i <
index->nkeycolumns;
i++)
8717 fullIndexScan =
true;
8722 if (fullIndexScan || indexQuals ==
NIL)
8734 outer_scans = loop_count;
8740 entryPagesFetched = numPendingPages;
8749 entryPagesFetched += ceil(counts.
searchEntries * rint(pow(numEntryPages, 0.15)));
8759 partialScale =
Min(partialScale, 1.0);
8761 entryPagesFetched += ceil(numEntryPages * partialScale);
8768 dataPagesFetched = ceil(numDataPages * partialScale);
8770 *indexStartupCost = 0;
8771 *indexTotalCost = 0;
8816 if (outer_scans > 1 || counts.
arrayScans > 1)
8818 entryPagesFetched *= outer_scans * counts.
arrayScans;
8821 numEntryPages,
root);
8822 entryPagesFetched /= outer_scans;
8823 dataPagesFetched *= outer_scans * counts.
arrayScans;
8826 numDataPages,
root);
8827 dataPagesFetched /= outer_scans;
8834 *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
8844 dataPagesFetched = ceil(numDataPages * counts.
exactEntries / numEntries);
8857 dataPagesFetchedBySel = ceil(*indexSelectivity *
8858 (numTuples / (BLCKSZ / 3)));
8859 if (dataPagesFetchedBySel > dataPagesFetched)
8860 dataPagesFetched = dataPagesFetchedBySel;
8872 if (outer_scans > 1 || counts.
arrayScans > 1)
8874 dataPagesFetched *= outer_scans * counts.
arrayScans;
8877 numDataPages,
root);
8878 dataPagesFetched /= outer_scans;
8882 *indexTotalCost += *indexStartupCost +
8883 dataPagesFetched * spc_random_page_cost;
8893 *indexStartupCost += qual_arg_cost;
8894 *indexTotalCost += qual_arg_cost;
8903 *indexPages = dataPagesFetched;
8911 Cost *indexStartupCost,
Cost *indexTotalCost,
8912 Selectivity *indexSelectivity,
double *indexCorrelation,
8917 double numPages =
index->pages;
8920 Cost spc_seq_page_cost;
8921 Cost spc_random_page_cost;
8922 double qual_arg_cost;
8923 double qualSelectivity;
8926 double minimalRanges;
8927 double estimatedRanges;
8937 &spc_random_page_cost,
8938 &spc_seq_page_cost);
8944 if (!
index->hypothetical)
8954 indexRanges =
Max(ceil((
double) baserel->
pages /
8963 indexRanges =
Max(ceil((
double) baserel->
pages /
8978 *indexCorrelation = 0;
8998 "no function provided to release variable stats with");
9029 elog(
ERROR,
"no function provided to release variable stats with");
9049 double varCorrelation = 0.0;
9052 varCorrelation = fabs(sslot.
numbers[0]);
9054 if (varCorrelation > *indexCorrelation)
9055 *indexCorrelation = varCorrelation;
9072 minimalRanges = ceil(indexRanges * qualSelectivity);
9079 if (*indexCorrelation < 1.0e-10)
9080 estimatedRanges = indexRanges;
9082 estimatedRanges =
Min(minimalRanges / *indexCorrelation, indexRanges);
9085 selec = estimatedRanges / indexRanges;
9089 *indexSelectivity = selec;
9104 *indexStartupCost += qual_arg_cost;
9111 *indexTotalCost = *indexStartupCost +
9112 spc_random_page_cost * (numPages - statsData.
revmapNumPages) * loop_count;
9124 *indexPages =
index->pages;
Datum idx(PG_FUNCTION_ARGS)
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
StrategyNumber IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, bool missing_ok)
CompareType IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, bool missing_ok)
#define DatumGetArrayTypeP(X)
Selectivity scalararraysel_containment(PlannerInfo *root, Node *leftop, Node *rightop, Oid elemtype, bool isEquality, bool useOr, int varRelid)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int ArrayGetNItems(int ndim, const int *dims)
#define AttrNumberIsForUserDefinedAttr(attributeNumber)
#define InvalidAttrNumber
Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
int bms_next_member(const Bitmapset *a, int prevbit)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
#define InvalidBlockNumber
static Datum values[MAXATTR]
void brinGetStats(Relation index, BrinStatsData *stats)
#define BRIN_DEFAULT_PAGES_PER_RANGE
#define REVMAP_PAGE_MAXITEMS
void ReleaseBuffer(Buffer buffer)
#define TextDatumGetCString(d)
#define PG_USED_FOR_ASSERTS_ONLY
#define MemSet(start, val, len)
#define OidIsValid(objectId)
int NumRelids(PlannerInfo *root, Node *clause)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
bool contain_volatile_functions(Node *clause)
double expression_returns_set_rows(PlannerInfo *root, Node *clause)
Selectivity clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Selectivity clause_selectivity(PlannerInfo *root, Node *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
double index_pages_fetched(double tuples_fetched, BlockNumber pages, double index_pages, PlannerInfo *root)
void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)
double clamp_row_est(double nrows)
double cpu_index_tuple_cost
double date2timestamp_no_overflow(DateADT dateVal)
static TimeTzADT * DatumGetTimeTzADTP(Datum X)
static DateADT DatumGetDateADT(Datum X)
static TimeADT DatumGetTimeADT(Datum X)
Datum datumCopy(Datum value, bool typByVal, int typLen)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
int errmsg_internal(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2, Oid opfamily)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx)
Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
void set_fn_opclass_options(FmgrInfo *flinfo, bytea *options)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)
Datum DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)
Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7)
#define DatumGetByteaPP(X)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define DirectFunctionCall1(func, arg1)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
#define PG_GETARG_INT32(n)
#define PG_GET_COLLATION()
#define PG_GETARG_INT16(n)
#define GIN_EXTRACTQUERY_PROC
#define GIN_SEARCH_MODE_DEFAULT
#define GIN_SEARCH_MODE_INCLUDE_EMPTY
void ginGetStats(Relation index, GinStatsData *stats)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys, int norderbys)
void index_close(Relation relation, LOCKMODE lockmode)
ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
bool index_fetch_heap(IndexScanDesc scan, TupleTableSlot *slot)
void index_endscan(IndexScanDesc scan)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
bool match_index_to_operand(Node *operand, int indexcol, IndexOptInfo *index)
if(TABLE==NULL||TABLE_index==NULL)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
ItemPointerData * ItemPointer
List * lappend(List *list, void *datum)
List * list_concat(List *list1, const List *list2)
List * list_copy(const List *oldlist)
bool list_member_ptr(const List *list, const void *datum)
void list_free(List *list)
bool list_member_int(const List *list, int datum)
void list_free_deep(List *list)
char * get_rel_name(Oid relid)
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
RegProcedure get_oprrest(Oid opno)
void free_attstatsslot(AttStatsSlot *sslot)
bool comparison_ops_are_compatible(Oid opno1, Oid opno2)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
RegProcedure get_oprjoin(Oid opno)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
RegProcedure get_opcode(Oid opno)
int get_op_opfamily_strategy(Oid opno, Oid opfamily)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
bool get_func_leakproof(Oid funcid)
char * get_func_name(Oid funcid)
Oid get_base_element_type(Oid typid)
Oid get_opfamily_method(Oid opfid)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Oid get_negator(Oid opno)
Oid get_commutator(Oid opno)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
MVNDistinct * statext_ndistinct_load(Oid mvoid, bool inh)
double convert_network_to_scalar(Datum value, Oid typid, bool *failure)
Size hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
static Node * get_rightop(const void *clause)
static bool is_opclause(const void *clause)
static bool is_funcclause(const void *clause)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
#define PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_PLACEHOLDERS
#define PVC_RECURSE_WINDOWFUNCS
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
#define IS_SIMPLE_REL(rel)
#define planner_rt_fetch(rti, root)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_delete_current(lst, var_or_cell)
#define for_each_from(cell, lst, N)
static void * list_nth(const List *list, int n)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
static int list_nth_int(const List *list, int n)
pg_locale_t pg_newlocale_from_collation(Oid collid)
size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
FormData_pg_statistic * Form_pg_statistic
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
bool has_unique_index(RelOptInfo *rel, AttrNumber attno)
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
static uint32 DatumGetUInt32(Datum X)
static bool DatumGetBool(Datum X)
static int64 DatumGetInt64(Datum X)
static Datum PointerGetDatum(const void *X)
static float4 DatumGetFloat4(Datum X)
static Oid DatumGetObjectId(Datum X)
static Datum Int16GetDatum(int16 X)
static Datum UInt16GetDatum(uint16 X)
static Datum BoolGetDatum(bool X)
static float8 DatumGetFloat8(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
static char DatumGetChar(Datum X)
static Datum Int32GetDatum(int32 X)
static int16 DatumGetInt16(Datum X)
static int32 DatumGetInt32(Datum X)
bool predicate_implied_by(List *predicate_list, List *clause_list, bool weak)
GlobalVisState * GlobalVisTestFor(Relation rel)
#define RelationGetRelationName(relation)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * find_base_rel_noerr(PlannerInfo *root, int relid)
RelOptInfo * find_join_rel(PlannerInfo *root, Relids relids)
Node * remove_nulling_relids(Node *node, const Bitmapset *removable_relids, const Bitmapset *except_relids)
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
static bool get_actual_variable_endpoint(Relation heapRel, Relation indexRel, ScanDirection indexscandir, ScanKey scankeys, int16 typLen, bool typByVal, TupleTableSlot *tableslot, MemoryContext outercontext, Datum *endpointDatum)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
Datum neqsel(PG_FUNCTION_ARGS)
static RelOptInfo * find_join_input_rel(PlannerInfo *root, Relids relids)
void mergejoinscansel(PlannerInfo *root, Node *clause, Oid opfamily, CompareType cmptype, bool nulls_first, Selectivity *leftstart, Selectivity *leftend, Selectivity *rightstart, Selectivity *rightend)
bool all_rows_selectable(PlannerInfo *root, Index varno, Bitmapset *varattnos)
static bool get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop, Oid collation, Datum *min, Datum *max)
void btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
List * get_quals_from_indexclauses(List *indexclauses)
static void convert_string_to_scalar(char *value, double *scaledvalue, char *lobound, double *scaledlobound, char *hibound, double *scaledhibound)
double var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, Datum constval, bool constisnull, bool varonleft, bool negate)
List * add_predicate_to_index_quals(IndexOptInfo *index, List *indexQuals)
double generic_restriction_selectivity(PlannerInfo *root, Oid oproid, Oid collation, List *args, int varRelid, double default_selectivity)
#define VISITED_PAGES_LIMIT
void spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
static double eqjoinsel_inner(FmgrInfo *eqproc, Oid collation, Oid hashLeft, Oid hashRight, VariableStatData *vardata1, VariableStatData *vardata2, double nd1, double nd2, bool isdefault1, bool isdefault2, AttStatsSlot *sslot1, AttStatsSlot *sslot2, Form_pg_statistic stats1, Form_pg_statistic stats2, bool have_mcvs1, bool have_mcvs2, bool *hasmatch1, bool *hasmatch2, int *p_nmatches)
Datum scalargtsel(PG_FUNCTION_ARGS)
#define DEFAULT_PAGE_CPU_MULTIPLIER
static bool estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, List **varinfos, double *ndistinct)
Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Datum eqjoinsel(PG_FUNCTION_ARGS)
double estimate_array_length(PlannerInfo *root, Node *arrayexpr)
double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, double *sumcommonp)
Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
static void examine_simple_variable(PlannerInfo *root, Var *var, VariableStatData *vardata)
static List * add_unique_group_var(PlannerInfo *root, List *varinfos, Node *var, VariableStatData *vardata)
Datum matchingsel(PG_FUNCTION_ARGS)
Datum eqsel(PG_FUNCTION_ARGS)
static bool mcvs_equal(MCVHashTable_hash *tab, Datum key0, Datum key1)
void examine_variable(PlannerInfo *root, Node *node, int varRelid, VariableStatData *vardata)
Datum scalargtjoinsel(PG_FUNCTION_ARGS)
static double convert_one_string_to_scalar(char *value, int rangelo, int rangehi)
static Datum scalarineqsel_wrapper(PG_FUNCTION_ARGS, bool isgt, bool iseq)
void gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
static void eqjoinsel_find_matches(FmgrInfo *eqproc, Oid collation, Oid hashLeft, Oid hashRight, bool op_is_reversed, AttStatsSlot *sslot1, AttStatsSlot *sslot2, int nvalues1, int nvalues2, bool *hasmatch1, bool *hasmatch2, int *p_nmatches, double *p_matchprodfreq)
static double convert_timevalue_to_scalar(Datum value, Oid typid, bool *failure)
static double convert_numeric_to_scalar(Datum value, Oid typid, bool *failure)
#define EQJOINSEL_MCV_HASH_THRESHOLD
static Node * strip_array_coercion(Node *node)
double estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, List **pgset, EstimationInfo *estinfo)
static bool convert_to_scalar(Datum value, Oid valuetypid, Oid collid, double *scaledvalue, Datum lobound, Datum hibound, Oid boundstypid, double *scaledlobound, double *scaledhibound)
double ineq_histogram_selectivity(PlannerInfo *root, VariableStatData *vardata, Oid opoid, FmgrInfo *opproc, bool isgt, bool iseq, Oid collation, Datum constval, Oid consttype)
void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, GenericCosts *costs)
List * estimate_multivariate_bucketsize(PlannerInfo *root, RelOptInfo *inner, List *hashclauses, Selectivity *innerbucketsize)
Datum scalarltjoinsel(PG_FUNCTION_ARGS)
static bool gincost_pattern(IndexOptInfo *index, int indexcol, Oid clause_op, Datum query, GinQualCounts *counts)
struct MCVHashTable_hash MCVHashTable_hash
void brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
void gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
Datum scalargejoinsel(PG_FUNCTION_ARGS)
static double eqjoinsel_semi(FmgrInfo *eqproc, Oid collation, Oid hashLeft, Oid hashRight, bool op_is_reversed, VariableStatData *vardata1, VariableStatData *vardata2, double nd1, double nd2, bool isdefault1, bool isdefault2, AttStatsSlot *sslot1, AttStatsSlot *sslot2, Form_pg_statistic stats1, Form_pg_statistic stats2, bool have_mcvs1, bool have_mcvs2, bool *hasmatch1, bool *hasmatch2, int *p_nmatches, RelOptInfo *inner_rel)
get_index_stats_hook_type get_index_stats_hook
Datum matchingjoinsel(PG_FUNCTION_ARGS)
static bool gincost_scalararrayopexpr(PlannerInfo *root, IndexOptInfo *index, int indexcol, ScalarArrayOpExpr *clause, double numIndexEntries, GinQualCounts *counts)
struct MCVHashEntry MCVHashEntry
double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, int min_hist_size, int n_skip, int *hist_size)
static uint32 hash_mcv(MCVHashTable_hash *tab, Datum key)
Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
static void examine_indexcol_variable(PlannerInfo *root, IndexOptInfo *index, int indexcol, VariableStatData *vardata)
struct MCVHashContext MCVHashContext
Datum scalarlesel(PG_FUNCTION_ARGS)
Datum scalargesel(PG_FUNCTION_ARGS)
static double scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, Oid collation, VariableStatData *vardata, Datum constval, Oid consttype)
static double convert_one_bytea_to_scalar(unsigned char *value, int valuelen, int rangelo, int rangehi)
Selectivity scalararraysel(PlannerInfo *root, ScalarArrayOpExpr *clause, bool is_join_clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
Datum scalarltsel(PG_FUNCTION_ARGS)
static double btcost_correlation(IndexOptInfo *index, VariableStatData *vardata)
double var_eq_non_const(VariableStatData *vardata, Oid oproid, Oid collation, Node *other, bool varonleft, bool negate)
static bool get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop, Oid collation, Datum *min, Datum *max)
Datum scalarlejoinsel(PG_FUNCTION_ARGS)
double get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
void hashcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
Datum neqjoinsel(PG_FUNCTION_ARGS)
double estimate_hashagg_tablesize(PlannerInfo *root, Path *path, const AggClauseCosts *agg_costs, double dNumGroups)
void estimate_hash_bucket_stats(PlannerInfo *root, Node *hashkey, double nbuckets, Selectivity *mcv_freq, Selectivity *bucketsize_frac)
static void convert_bytea_to_scalar(Datum value, double *scaledvalue, Datum lobound, double *scaledlobound, Datum hibound, double *scaledhibound)
Cost index_other_operands_eval_cost(PlannerInfo *root, List *indexquals)
get_relation_stats_hook_type get_relation_stats_hook
Selectivity rowcomparesel(PlannerInfo *root, RowCompareExpr *clause, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
static bool gincost_opexpr(PlannerInfo *root, IndexOptInfo *index, int indexcol, OpExpr *clause, GinQualCounts *counts)
static void ReleaseDummy(HeapTuple tuple)
static char * convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure)
static double eqsel_internal(PG_FUNCTION_ARGS, bool negate)
static void get_stats_slot_range(AttStatsSlot *sslot, Oid opfuncoid, FmgrInfo *opproc, Oid collation, int16 typLen, bool typByVal, Datum *min, Datum *max, bool *p_have_data)
void get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo, VariableStatData *vardata1, VariableStatData *vardata2, bool *join_is_reversed)
#define DEFAULT_NOT_UNK_SEL
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
bool(* get_relation_stats_hook_type)(PlannerInfo *root, RangeTblEntry *rte, AttrNumber attnum, VariableStatData *vardata)
#define DEFAULT_RANGE_INEQ_SEL
bool(* get_index_stats_hook_type)(PlannerInfo *root, Oid indexOid, AttrNumber indexattnum, VariableStatData *vardata)
#define DEFAULT_MATCHING_SEL
#define DEFAULT_NUM_DISTINCT
#define SELFLAG_USED_DEFAULT
#define InitNonVacuumableSnapshot(snapshotdata, vistestp)
void get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost, double *spc_seq_page_cost)
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
BlockNumber revmapNumPages
BlockNumber pagesPerRange
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Selectivity indexSelectivity
double spc_random_page_cost
bool attHasNormalScan[INDEX_MAX_KEYS]
bool attHasFullScan[INDEX_MAX_KEYS]
BlockNumber nPendingPages
struct TupleDescData * xs_itupdesc
FunctionCallInfo hash_fcinfo
FunctionCallInfo equal_fcinfo
MVNDistinctItem items[FLEXIBLE_ARRAY_MEMBER]
NullTestType nulltesttype
void(* freefunc)(HeapTuple tuple)
#define FirstLowInvalidHeapAttributeNumber
#define TableOidAttributeNumber
#define SelfItemPointerAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
static Interval * DatumGetIntervalP(Datum X)
static Timestamp DatumGetTimestamp(Datum X)
static TimestampTz DatumGetTimestampTz(Datum X)
Relids pull_varnos(PlannerInfo *root, Node *node)
List * pull_var_clause(Node *node, int flags)
static Size VARSIZE_ANY_EXHDR(const void *PTR)
static char * VARDATA_ANY(const void *PTR)
#define VM_ALL_VISIBLE(r, b, v)