132#include "utils/fmgroids.h"
145#define DEFAULT_PAGE_CPU_MULTIPLIER 50.0
154 double nd1,
double nd2,
155 bool isdefault1,
bool isdefault2,
158 bool have_mcvs1,
bool have_mcvs2);
161 double nd1,
double nd2,
162 bool isdefault1,
bool isdefault2,
165 bool have_mcvs1,
bool have_mcvs2,
172 double *scaledlobound,
double *scaledhibound);
177 double *scaledlobound,
179 double *scaledhibound);
183 double *scaledlobound,
185 double *scaledhibound);
187 int rangelo,
int rangehi);
189 int rangelo,
int rangehi);
199 Oid sortop,
Oid collation,
203 Oid collation,
int16 typLen,
bool typByVal,
207 Oid sortop,
Oid collation,
217 Datum *endpointDatum);
272 &vardata, &other, &varonleft))
282 ((
Const *) other)->constvalue,
283 ((
Const *) other)->constisnull,
301 Datum constval,
bool constisnull,
302 bool varonleft,
bool negate)
305 double nullfrac = 0.0;
325 nullfrac = stats->stanullfrac;
371 fcinfo->args[0].isnull =
false;
372 fcinfo->args[1].isnull =
false;
375 fcinfo->args[1].value = constval;
377 fcinfo->args[0].value = constval;
384 fcinfo->args[0].value = sslot.
values[
i];
386 fcinfo->args[1].value = sslot.
values[
i];
387 fcinfo->isnull =
false;
417 double sumcommon = 0.0;
418 double otherdistinct;
422 selec = 1.0 - sumcommon - nullfrac;
432 if (otherdistinct > 1)
433 selec /= otherdistinct;
457 selec = 1.0 - selec - nullfrac;
473 bool varonleft,
bool negate)
476 double nullfrac = 0.0;
487 nullfrac = stats->stanullfrac;
516 selec = 1.0 - nullfrac;
546 selec = 1.0 - selec - nullfrac;
630 if (block >= vardata->
rel->
pages - 1)
645 block +=
Min(offset / density, 1.0);
652 selec = block / (vardata->
rel->
pages - 0.5);
662 if (iseq == isgt && vardata->
rel->
tuples >= 1.0)
686 mcv_selec =
mcv_selectivity(vardata, &opproc, collation, constval,
true,
694 operator, &opproc, isgt, iseq,
696 constval, consttype);
703 selec = 1.0 - stats->stanullfrac - sumcommon;
705 if (hist_selec >= 0.0)
738 Datum constval,
bool varonleft,
766 fcinfo->args[0].isnull =
false;
767 fcinfo->args[1].isnull =
false;
770 fcinfo->args[1].value = constval;
772 fcinfo->args[0].value = constval;
779 fcinfo->args[0].value = sslot.
values[
i];
781 fcinfo->args[1].value = sslot.
values[
i];
782 fcinfo->isnull =
false;
791 *sumcommonp = sumcommon;
830 Datum constval,
bool varonleft,
831 int min_hist_size,
int n_skip,
839 Assert(min_hist_size > 2 * n_skip);
848 if (sslot.
nvalues >= min_hist_size)
864 fcinfo->args[0].isnull =
false;
865 fcinfo->args[1].isnull =
false;
868 fcinfo->args[1].value = constval;
870 fcinfo->args[0].value = constval;
872 for (
i = n_skip;
i < sslot.
nvalues - n_skip;
i++)
877 fcinfo->args[0].value = sslot.
values[
i];
879 fcinfo->args[1].value = sslot.
values[
i];
880 fcinfo->isnull =
false;
885 result = ((double) nmatch) / ((double) (sslot.
nvalues - 2 * n_skip));
921 double default_selectivity)
933 &vardata, &other, &varonleft))
934 return default_selectivity;
941 ((
Const *) other)->constisnull)
950 Datum constval = ((
Const *) other)->constvalue;
978 selec = default_selectivity;
980 else if (hist_size < 100)
987 double hist_weight = hist_size / 100.0;
989 selec = selec * hist_weight +
990 default_selectivity * (1.0 - hist_weight);
996 else if (selec > 0.9999)
1010 selec *= 1.0 - nullfrac - mcvsum;
1016 selec = default_selectivity;
1048 Oid opoid,
FmgrInfo *opproc,
bool isgt,
bool iseq,
1100 bool have_end =
false;
1116 while (lobound < hibound)
1118 int probe = (lobound + hibound) / 2;
1126 if (probe == 0 && sslot.
nvalues > 2)
1148 lobound = probe + 1;
1165 else if (lobound >= sslot.
nvalues)
1176 double eq_selec = 0;
1198 if (
i == 1 || isgt == iseq)
1200 double otherdistinct;
1218 if (otherdistinct > 1)
1219 eq_selec = 1.0 / otherdistinct;
1238 else if (
val <= low)
1240 else if (
val >= high)
1244 binfrac = (
val - low) / (high - low);
1252 if (isnan(binfrac) ||
1253 binfrac < 0.0 || binfrac > 1.0)
1275 histfrac = (double) (
i - 1) + binfrac;
1276 histfrac /= (double) (sslot.
nvalues - 1);
1311 histfrac += eq_selec * (1.0 - binfrac);
1319 histfrac -= eq_selec;
1326 hist_selec = isgt ? (1.0 - histfrac) : histfrac;
1341 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1343 if (hist_selec < cutoff)
1344 hist_selec = cutoff;
1345 else if (hist_selec > 1.0 - cutoff)
1346 hist_selec = 1.0 - cutoff;
1363 fcinfo->args[0].isnull =
false;
1364 fcinfo->args[1].isnull =
false;
1365 fcinfo->args[1].value = constval;
1370 fcinfo->args[0].value = sslot.
values[
i];
1371 fcinfo->isnull =
false;
1376 hist_selec = ((double) nmatch) / ((double) sslot.
nvalues);
1385 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1387 if (hist_selec < cutoff)
1388 hist_selec = cutoff;
1389 else if (hist_selec > 1.0 - cutoff)
1390 hist_selec = 1.0 - cutoff;
1424 &vardata, &other, &varonleft))
1440 if (((
Const *) other)->constisnull)
1445 constval = ((
Const *) other)->constvalue;
1446 consttype = ((
Const *) other)->consttype;
1465 &vardata, constval, consttype);
1560 freq_null = stats->stanullfrac;
1576 freq_true = 1.0 - sslot.
numbers[0] - freq_null;
1582 freq_false = 1.0 - freq_true - freq_null;
1584 switch (booltesttype)
1592 selec = 1.0 - freq_null;
1600 selec = 1.0 - freq_true;
1608 selec = 1.0 - freq_false;
1611 elog(
ERROR,
"unrecognized booltesttype: %d",
1612 (
int) booltesttype);
1626 switch (booltesttype)
1634 selec = 1.0 - freq_null;
1639 selec = (1.0 - freq_null) / 2.0;
1645 selec = (freq_null + 1.0) / 2.0;
1648 elog(
ERROR,
"unrecognized booltesttype: %d",
1649 (
int) booltesttype);
1663 switch (booltesttype)
1684 elog(
ERROR,
"unrecognized booltesttype: %d",
1685 (
int) booltesttype);
1717 freq_null = stats->stanullfrac;
1719 switch (nulltesttype)
1734 selec = 1.0 - freq_null;
1737 elog(
ERROR,
"unrecognized nulltesttype: %d",
1738 (
int) nulltesttype);
1743 ((
Var *) vardata.
var)->varattno < 0)
1749 selec = (nulltesttype ==
IS_NULL) ? 0.0 : 1.0;
1756 switch (nulltesttype)
1765 elog(
ERROR,
"unrecognized nulltesttype: %d",
1766 (
int) nulltesttype);
1823 bool is_join_clause,
1829 bool useOr = clause->
useOr;
1830 bool isEquality =
false;
1831 bool isInequality =
false;
1834 Oid nominal_element_type;
1835 Oid nominal_element_collation;
1868 if (
operator == typentry->
eq_opr)
1871 isInequality =
true;
1880 if ((isEquality || isInequality) && !is_join_clause)
1883 nominal_element_type,
1884 isEquality, useOr, varRelid);
1909 if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
1911 else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
1912 isInequality =
true;
1926 if (rightop &&
IsA(rightop,
Const))
1928 Datum arraydatum = ((
Const *) rightop)->constvalue;
1929 bool arrayisnull = ((
Const *) rightop)->constisnull;
1943 &elmlen, &elmbyval, &elmalign);
1946 elmlen, elmbyval, elmalign,
1947 &elem_values, &elem_nulls, &num_elems);
1963 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
1965 for (
i = 0;
i < num_elems;
i++)
1973 nominal_element_collation,
1980 clause->inputcollid,
1988 clause->inputcollid,
2004 s1disjoint +=
s2 - 1.0;
2009 if ((useOr ? isEquality : isInequality) &&
2010 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2022 &elmlen, &elmbyval);
2031 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2033 foreach(l, arrayexpr->elements)
2047 clause->inputcollid,
2055 clause->inputcollid,
2071 s1disjoint +=
s2 - 1.0;
2076 if ((useOr ? isEquality : isInequality) &&
2077 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2093 dummyexpr->
typeId = nominal_element_type;
2094 dummyexpr->typeMod = -1;
2095 dummyexpr->collation = clause->inputcollid;
2099 clause->inputcollid,
2107 clause->inputcollid,
2112 s1 = useOr ? 0.0 : 1.0;
2119 for (
i = 0;
i < 10;
i++)
2149 if (arrayexpr &&
IsA(arrayexpr,
Const))
2151 Datum arraydatum = ((
Const *) arrayexpr)->constvalue;
2152 bool arrayisnull = ((
Const *) arrayexpr)->constisnull;
2165 else if (arrayexpr &&
root)
2218 bool is_join_clause;
2234 is_join_clause =
false;
2236 else if (sjinfo == NULL)
2242 is_join_clause =
false;
2301 bool have_mcvs1 =
false;
2302 bool have_mcvs2 =
false;
2304 bool join_is_reversed;
2308 &vardata1, &vardata2, &join_is_reversed);
2315 memset(&sslot1, 0,
sizeof(sslot1));
2316 memset(&sslot2, 0,
sizeof(sslot2));
2335 if (get_mcv_stats &&
2346 if (get_mcv_stats &&
2355 &vardata1, &vardata2,
2357 isdefault1, isdefault2,
2360 have_mcvs1, have_mcvs2);
2367 selec = selec_inner;
2380 if (!join_is_reversed)
2382 &vardata1, &vardata2,
2384 isdefault1, isdefault2,
2387 have_mcvs1, have_mcvs2,
2395 &vardata2, &vardata1,
2397 isdefault2, isdefault1,
2400 have_mcvs2, have_mcvs1,
2414 selec =
Min(selec, inner_rel->
rows * selec_inner);
2418 elog(
ERROR,
"unrecognized join type: %d",
2444 double nd1,
double nd2,
2445 bool isdefault1,
bool isdefault2,
2448 bool have_mcvs1,
bool have_mcvs2)
2452 if (have_mcvs1 && have_mcvs2)
2470 double nullfrac1 = stats1->stanullfrac;
2471 double nullfrac2 = stats2->stanullfrac;
2472 double matchprodfreq,
2494 fcinfo->args[0].isnull =
false;
2495 fcinfo->args[1].isnull =
false;
2506 matchprodfreq = 0.0;
2512 fcinfo->args[0].value = sslot1->
values[
i];
2520 fcinfo->args[1].value = sslot2->
values[
j];
2521 fcinfo->isnull =
false;
2525 hasmatch1[
i] = hasmatch2[
j] =
true;
2534 matchfreq1 = unmatchfreq1 = 0.0;
2540 unmatchfreq1 += sslot1->
numbers[
i];
2544 matchfreq2 = unmatchfreq2 = 0.0;
2550 unmatchfreq2 += sslot2->
numbers[
i];
2561 otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
2562 otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
2574 totalsel1 = matchprodfreq;
2576 totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->
nvalues);
2578 totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
2581 totalsel2 = matchprodfreq;
2583 totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->
nvalues);
2585 totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
2594 selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
2618 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2619 double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
2621 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
2641 double nd1,
double nd2,
2642 bool isdefault1,
bool isdefault2,
2645 bool have_mcvs1,
bool have_mcvs2,
2671 if (nd2 >= vardata2->
rel->
rows)
2677 if (nd2 >= inner_rel->
rows)
2679 nd2 = inner_rel->
rows;
2683 if (have_mcvs1 && have_mcvs2 &&
OidIsValid(opfuncoid))
2697 double nullfrac1 = stats1->stanullfrac;
2712 clamped_nvalues2 =
Min(sslot2->
nvalues, nd2);
2724 fcinfo->args[0].isnull =
false;
2725 fcinfo->args[1].isnull =
false;
2728 hasmatch2 = (
bool *)
palloc0(clamped_nvalues2 *
sizeof(
bool));
2741 fcinfo->args[0].value = sslot1->
values[
i];
2743 for (
j = 0;
j < clamped_nvalues2;
j++)
2749 fcinfo->args[1].value = sslot2->
values[
j];
2750 fcinfo->isnull =
false;
2754 hasmatch1[
i] = hasmatch2[
j] =
true;
2786 if (!isdefault1 && !isdefault2)
2790 if (nd1 <= nd2 || nd2 < 0)
2791 uncertainfrac = 1.0;
2793 uncertainfrac = nd2 / nd1;
2796 uncertainfrac = 0.5;
2797 uncertain = 1.0 - matchfreq1 - nullfrac1;
2799 selec = matchfreq1 + uncertainfrac * uncertain;
2807 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2809 if (!isdefault1 && !isdefault2)
2811 if (nd1 <= nd2 || nd2 < 0)
2812 selec = 1.0 - nullfrac1;
2814 selec = (nd2 / nd1) * (1.0 - nullfrac1);
2817 selec = 0.5 * (1.0 - nullfrac1);
2869 result = 1.0 - nullfrac;
2895 result = 1.0 - result;
2996 *leftstart = *rightstart = 0.0;
2997 *leftend = *rightend = 1.0;
3002 opno = ((
OpExpr *) clause)->opno;
3003 collation = ((
OpExpr *) clause)->inputcollid;
3035 if (op_lefttype == op_righttype)
3039 op_lefttype, op_righttype,
3042 op_lefttype, op_righttype,
3054 op_lefttype, op_righttype,
3057 op_lefttype, op_righttype,
3060 op_lefttype, op_lefttype,
3063 op_righttype, op_righttype,
3068 op_righttype, op_lefttype,
3071 op_righttype, op_lefttype,
3081 if (op_lefttype == op_righttype)
3085 op_lefttype, op_righttype,
3088 op_lefttype, op_righttype,
3093 op_lefttype, op_lefttype,
3102 op_lefttype, op_righttype,
3105 op_lefttype, op_righttype,
3108 op_lefttype, op_lefttype,
3111 op_righttype, op_righttype,
3114 op_lefttype, op_lefttype,
3117 op_righttype, op_righttype,
3120 op_righttype, op_lefttype,
3123 op_righttype, op_lefttype,
3145 &leftmin, &leftmax))
3148 &rightmin, &rightmax))
3155 &leftmax, &leftmin))
3158 &rightmax, &rightmin))
3168 rightmax, op_righttype);
3174 leftmax, op_lefttype);
3184 if (*leftend > *rightend)
3186 else if (*leftend < *rightend)
3189 *leftend = *rightend = 1.0;
3198 rightmin, op_righttype);
3204 leftmin, op_lefttype);
3206 *rightstart = selec;
3214 if (*leftstart < *rightstart)
3216 else if (*leftstart > *rightstart)
3219 *leftstart = *rightstart = 0.0;
3234 *leftstart += stats->stanullfrac;
3236 *leftend += stats->stanullfrac;
3242 *rightstart += stats->stanullfrac;
3244 *rightend += stats->stanullfrac;
3250 if (*leftstart >= *leftend)
3255 if (*rightstart >= *rightend)
3335 foreach(lc, varinfos)
3348 if (vardata->
rel != varinfo->
rel &&
3367 varinfo->
rel = vardata->
rel;
3370 varinfos =
lappend(varinfos, varinfo);
3450 double srf_multiplier = 1.0;
3456 if (estinfo != NULL)
3472 if (groupExprs ==
NIL || (pgset && *pgset ==
NIL))
3485 foreach(l, groupExprs)
3488 double this_srf_multiplier;
3509 if (srf_multiplier < this_srf_multiplier)
3510 srf_multiplier = this_srf_multiplier;
3513 if (
exprType(groupexpr) == BOOLOID)
3536 groupexpr, &vardata);
3559 if (varshere ==
NIL)
3569 foreach(l2, varshere)
3583 if (varinfos ==
NIL)
3586 numdistinct *= srf_multiplier;
3588 numdistinct = ceil(numdistinct);
3590 if (numdistinct > input_rows)
3591 numdistinct = input_rows;
3592 if (numdistinct < 1.0)
3609 double reldistinct = 1;
3610 double relmaxndistinct = reldistinct;
3611 int relvarcount = 0;
3619 relvarinfos =
lappend(relvarinfos, varinfo1);
3624 if (varinfo2->
rel == varinfo1->
rel)
3627 relvarinfos =
lappend(relvarinfos, varinfo2);
3632 newvarinfos =
lappend(newvarinfos, varinfo2);
3655 reldistinct *= mvndistinct;
3656 if (relmaxndistinct < mvndistinct)
3657 relmaxndistinct = mvndistinct;
3662 foreach(l, relvarinfos)
3667 if (relmaxndistinct < varinfo2->ndistinct)
3675 if (estinfo != NULL && varinfo2->
isdefault)
3697 double clamp = rel->
tuples;
3699 if (relvarcount > 1)
3702 if (clamp < relmaxndistinct)
3704 clamp = relmaxndistinct;
3710 if (reldistinct > clamp)
3711 reldistinct = clamp;
3718 if (reldistinct > 0 && rel->
rows < rel->
tuples)
3756 rel->
tuples / reldistinct));
3763 numdistinct *= reldistinct;
3766 varinfos = newvarinfos;
3767 }
while (varinfos !=
NIL);
3770 numdistinct *= srf_multiplier;
3773 numdistinct = ceil(numdistinct);
3776 if (numdistinct > input_rows)
3777 numdistinct = input_rows;
3778 if (numdistinct < 1.0)
3804 double ndistinct = 1.0;
3814 while (clauses !=
NIL)
3821 List *origin_varinfos;
3822 int group_relid = -1;
3833 foreach(lc, clauses)
3845 relids = rinfo->outer_is_left ?
3846 rinfo->right_relids : rinfo->left_relids;
3847 expr = rinfo->outer_is_left ?
3851 root->simple_rel_array[relid]->statlist !=
NIL)
3853 bool is_duplicate =
false;
3859 if (group_relid < 0)
3863 if (!rte || (rte->relkind != RELKIND_RELATION &&
3864 rte->relkind != RELKIND_MATVIEW &&
3865 rte->relkind != RELKIND_FOREIGN_TABLE &&
3866 rte->relkind != RELKIND_PARTITIONED_TABLE))
3869 otherclauses =
lappend(otherclauses, rinfo);
3874 group_relid = relid;
3875 group_rel =
root->simple_rel_array[relid];
3877 else if (group_relid != relid)
3912 foreach(lc1, varinfos)
3919 is_duplicate =
true;
3938 varinfo->
var = expr;
3939 varinfo->
rel =
root->simple_rel_array[relid];
3940 varinfos =
lappend(varinfos, varinfo);
3946 origin_rinfos =
lappend(origin_rinfos, rinfo);
3951 otherclauses =
lappend(otherclauses, rinfo);
3963 otherclauses =
list_concat(otherclauses, origin_rinfos);
3969 Assert(group_rel != NULL);
3972 origin_varinfos = varinfos;
3988 if (ndistinct < mvndistinct)
3989 ndistinct = mvndistinct;
3990 Assert(ndistinct >= 1.0);
3996 forboth(lc1, origin_varinfos, lc2, origin_rinfos)
4009 *innerbucketsize = 1.0 / ndistinct;
4010 return otherclauses;
4109 stanullfrac = stats->stanullfrac;
4115 avgfreq = (1.0 - stanullfrac) / ndistinct;
4136 if (ndistinct > nbuckets)
4137 estfract = 1.0 / nbuckets;
4139 estfract = 1.0 / ndistinct;
4144 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
4145 estfract *= *mcv_freq / avgfreq;
4152 if (estfract < 1.0e-6)
4154 else if (estfract > 1.0)
4182 path->pathtarget->width,
4191 return hashentrysize * dNumGroups;
4218 List **varinfos,
double *ndistinct)
4239 int nshared_vars = 0;
4240 int nshared_exprs = 0;
4243 if (info->
kind != STATS_EXT_NDISTINCT)
4255 foreach(lc2, *varinfos)
4283 foreach(lc3, info->
exprs)
4301 if (nshared_vars + nshared_exprs < 2)
4312 if ((nshared_exprs > nmatches_exprs) ||
4313 (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
4316 nmatches_vars = nshared_vars;
4317 nmatches_exprs = nshared_exprs;
4318 matched_info = info;
4326 Assert(nmatches_vars + nmatches_exprs > 1);
4348 if (matched_info->
exprs)
4354 foreach(lc2, *varinfos)
4402 foreach(lc3, matched_info->
exprs)
4469 elog(
ERROR,
"corrupt MVNDistinct entry");
4472 foreach(lc, *varinfos)
4494 newlist =
lappend(newlist, varinfo);
4503 newlist =
lappend(newlist, varinfo);
4519 foreach(lc3, matched_info->
exprs)
4534 newlist =
lappend(newlist, varinfo);
4537 *varinfos = newlist;
4577 double *scaledlobound,
double *scaledhibound)
4579 bool failure =
false;
4613 case REGPROCEDUREOID:
4615 case REGOPERATOROID:
4618 case REGCOLLATIONOID:
4620 case REGDICTIONARYOID:
4622 case REGNAMESPACEOID:
4656 lostr, scaledlobound,
4657 histr, scaledhibound);
4670 if (boundstypid != BYTEAOID)
4673 lobound, scaledlobound,
4674 hibound, scaledhibound);
4682 case TIMESTAMPTZOID:
4711 *scaledvalue = *scaledlobound = *scaledhibound = 0;
4745 case REGPROCEDUREOID:
4747 case REGOPERATOROID:
4750 case REGCOLLATIONOID:
4752 case REGDICTIONARYOID:
4754 case REGNAMESPACEOID:
4785 double *scaledvalue,
4787 double *scaledlobound,
4789 double *scaledhibound)
4795 rangelo = rangehi = (
unsigned char) hibound[0];
4796 for (sptr = lobound; *sptr; sptr++)
4798 if (rangelo > (
unsigned char) *sptr)
4799 rangelo = (
unsigned char) *sptr;
4800 if (rangehi < (
unsigned char) *sptr)
4801 rangehi = (
unsigned char) *sptr;
4803 for (sptr = hibound; *sptr; sptr++)
4805 if (rangelo > (
unsigned char) *sptr)
4806 rangelo = (
unsigned char) *sptr;
4807 if (rangehi < (
unsigned char) *sptr)
4808 rangehi = (
unsigned char) *sptr;
4811 if (rangelo <= 'Z' && rangehi >=
'A')
4819 if (rangelo <= 'z' && rangehi >=
'a')
4827 if (rangelo <= '9' && rangehi >=
'0')
4839 if (rangehi - rangelo < 9)
4850 if (*lobound != *hibound || *lobound != *
value)
4852 lobound++, hibound++,
value++;
4866 int slen = strlen(
value);
4887 base = rangehi - rangelo + 1;
4892 int ch = (
unsigned char) *
value++;
4896 else if (ch > rangehi)
4898 num += ((double) (ch - rangelo)) / denom;
4973 if (xfrmlen == INT_MAX)
4976 xfrmstr = (
char *)
palloc(xfrmlen + 1);
4983 Assert(xfrmlen2 <= xfrmlen);
5004 double *scaledvalue,
5006 double *scaledlobound,
5008 double *scaledhibound)
5020 unsigned char *valstr = (
unsigned char *)
VARDATA_ANY(valuep);
5021 unsigned char *lostr = (
unsigned char *)
VARDATA_ANY(loboundp);
5022 unsigned char *histr = (
unsigned char *)
VARDATA_ANY(hiboundp);
5033 minlen =
Min(
Min(valuelen, loboundlen), hiboundlen);
5034 for (
i = 0;
i < minlen;
i++)
5036 if (*lostr != *histr || *lostr != *valstr)
5038 lostr++, histr++, valstr++;
5039 loboundlen--, hiboundlen--, valuelen--;
5052 int rangelo,
int rangehi)
5069 base = rangehi - rangelo + 1;
5072 while (valuelen-- > 0)
5078 else if (ch > rangehi)
5080 num += ((double) (ch - rangelo)) / denom;
5100 case TIMESTAMPTZOID:
5127 return (
double) (timetz->
time + (timetz->
zone * 1000000.0));
5185 if (vardata->
rel && rdata.
rel == NULL)
5193 if (vardata->
rel == NULL && rdata.
rel)
5222 bool *join_is_reversed)
5228 elog(
ERROR,
"join operator should take two arguments");
5236 if (vardata1->
rel &&
5238 *join_is_reversed =
true;
5239 else if (vardata2->
rel &&
5241 *join_is_reversed =
true;
5243 *join_is_reversed =
false;
5312 if (
IsA(basenode,
Var) &&
5313 (varRelid == 0 || varRelid == ((
Var *) basenode)->varno))
5315 Var *var = (
Var *) basenode;
5318 vardata->
var = basenode;
5320 vardata->
atttype = var->vartype;
5351 if (varRelid == 0 || varRelid == relid)
5354 vardata->
rel = onerel;
5381 vardata->
var = node;
5430 if (indexpr_item == NULL)
5433 for (pos = 0; pos <
index->ncolumns; pos++)
5435 if (
index->indexkeys[pos] == 0)
5439 if (indexpr_item == NULL)
5440 elog(
ERROR,
"too few entries in indexprs list");
5444 if (
equal(node, indexkey))
5450 if (
index->unique &&
5451 index->nkeycolumns == 1 &&
5477 elog(
ERROR,
"no function provided to release variable stats with");
5506 rte->securityQuals ==
NIL &&
5527 root->append_rel_array != NULL)
5532 appinfo =
root->append_rel_array[varno];
5538 appinfo =
root->append_rel_array[varno];
5540 if (varno !=
index->rel->relid)
5547 rte->securityQuals ==
NIL &&
5563 indexpr_item =
lnext(
index->indexprs, indexpr_item);
5591 if (info->
kind != STATS_EXT_EXPRESSIONS)
5599 foreach(expr_item, info->
exprs)
5610 if (
equal(node, expr))
5630 rte->securityQuals ==
NIL &&
5648 root->append_rel_array != NULL)
5653 appinfo =
root->append_rel_array[varno];
5659 appinfo =
root->append_rel_array[varno];
5661 if (varno != onerel->
relid)
5668 rte->securityQuals ==
NIL &&
5712 elog(
ERROR,
"no function provided to release variable stats with");
5754 rte->securityQuals ==
NIL &&
5771 root->append_rel_array != NULL)
5778 appinfo =
root->append_rel_array[varno];
5791 int parent_varattno;
5796 parent_varattno = appinfo->parent_colnos[varattno - 1];
5797 if (parent_varattno == 0)
5801 varattno = parent_varattno;
5805 appinfo =
root->append_rel_array[varno];
5825 rte->securityQuals ==
NIL &&
5892 while (levelsup-- > 0)
5894 cteroot = cteroot->parent_root;
5924 if (subroot == NULL)
5935 subquery = subroot->
parse;
5956 if (ste == NULL || ste->resjunk)
5957 elog(
ERROR,
"subquery %s does not have attribute %d",
5958 rte->eref->aliasname, var->
varattno);
5999 if (rte->security_barrier)
6003 if (var &&
IsA(var,
Var) &&
6054 if (
index->indexkeys[indexcol] != 0)
6062 colnum =
index->indexkeys[indexcol];
6074 elog(
ERROR,
"no function provided to release variable stats with");
6088 relid =
index->indexoid;
6089 colnum = indexcol + 1;
6100 elog(
ERROR,
"no function provided to release variable stats with");
6132 (
errmsg_internal(
"not using statistics because function \"%s\" is not leakproof",
6152 double stanullfrac = 0.0;
6169 stadistinct = stats->stadistinct;
6170 stanullfrac = stats->stanullfrac;
6172 else if (vardata->
vartype == BOOLOID)
6201 switch (((
Var *) vardata->
var)->varattno)
6230 stadistinct = -1.0 * (1.0 - stanullfrac);
6235 if (stadistinct > 0.0)
6241 if (vardata->
rel == NULL)
6256 if (stadistinct < 0.0)
6283 Oid sortop,
Oid collation,
6288 bool have_data =
false;
6333 STATISTIC_KIND_HISTOGRAM, sortop,
6357 collation, typLen, typByVal,
6358 &tmin, &tmax, &have_data);
6375 bool use_mcvs = have_data;
6379 double sumcommon = 0.0;
6386 if (sumcommon + nullfrac > 0.99999)
6392 collation, typLen, typByVal,
6393 &tmin, &tmax, &have_data);
6410 Oid collation,
int16 typLen,
bool typByVal,
6415 bool have_data = *p_have_data;
6416 bool found_tmin =
false;
6417 bool found_tmax =
false;
6420 if (opproc->
fn_oid != opfuncoid)
6428 tmin = tmax = sslot->
values[
i];
6429 found_tmin = found_tmax =
true;
6430 *p_have_data = have_data =
true;
6453 *min =
datumCopy(tmin, typByVal, typLen);
6455 *max =
datumCopy(tmax, typByVal, typLen);
6473 Oid sortop,
Oid collation,
6476 bool have_data =
false;
6485 rte =
root->simple_rte_array[rel->
relid];
6489 if (rte->relkind == RELKIND_PARTITIONED_TABLE)
6500 if (
index->sortopfamily == NULL)
6514 if (
index->hypothetical)
6521 if (collation !=
index->indexcollations[0])
6529 if (
index->reverse_sort[0])
6535 if (
index->reverse_sort[0])
6561 "get_actual_variable_range workspace",
6606 if (max && have_data)
6662 Datum *endpointDatum)
6664 bool have_data =
false;
6669 int n_visited_heap_pages = 0;
6723 &SnapshotNonVacuumable, NULL,
6751#define VISITED_PAGES_LIMIT 100
6753 if (block != last_heap_block)
6755 last_heap_block = block;
6756 n_visited_heap_pages++;
6778 elog(
ERROR,
"no data returned for index-only scan");
6793 elog(
ERROR,
"found unexpected null value in index \"%s\"",
6834 elog(
ERROR,
"could not find RelOptInfo for given relids");
6856 foreach(lc, indexclauses)
6865 result =
lappend(result, rinfo);
6883 Cost qual_arg_cost = 0;
6886 foreach(lc, indexquals)
6889 Node *other_operand;
6919 other_operand = NULL;
6923 elog(
ERROR,
"unsupported indexqual type: %d",
6925 other_operand = NULL;
6931 return qual_arg_cost;
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;
6953 double qual_op_cost;
6954 double qual_arg_cost;
6955 List *selectivityQuals;
6971 if (num_sa_scans < 1)
6974 foreach(l, indexQuals)
6984 num_sa_scans *= alength;
7001 if (numIndexTuples <= 0.0)
7003 numIndexTuples = indexSelectivity *
index->rel->tuples;
7012 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7020 if (numIndexTuples >
index->tuples)
7021 numIndexTuples =
index->tuples;
7022 if (numIndexTuples < 1.0)
7023 numIndexTuples = 1.0;
7038 numIndexPages = ceil(numIndexTuples *
index->pages /
index->tuples);
7040 numIndexPages = 1.0;
7044 &spc_random_page_cost,
7064 num_outer_scans = loop_count;
7065 num_scans = num_sa_scans * num_outer_scans;
7069 double pages_fetched;
7072 pages_fetched = numIndexPages * num_scans;
7077 (
double)
index->pages,
7085 indexTotalCost = (pages_fetched * spc_random_page_cost)
7094 indexTotalCost = numIndexPages * spc_random_page_cost;
7116 indexStartupCost = qual_arg_cost;
7117 indexTotalCost += qual_arg_cost;
7123 indexCorrelation = 0.0;
7166 foreach(lc,
index->indpred)
7172 predExtraQuals =
list_concat(predExtraQuals, oneQual);
7193 double indexCorrelation = 0;
7198 index->opcintype[0],
7199 index->opcintype[0],
7203 STATISTIC_KIND_CORRELATION, sortop,
7206 double varCorrelation;
7209 varCorrelation = sslot.
numbers[0];
7211 if (
index->reverse_sort[0])
7212 varCorrelation = -varCorrelation;
7214 if (
index->nkeycolumns > 1)
7215 indexCorrelation = varCorrelation * 0.75;
7217 indexCorrelation = varCorrelation;
7222 return indexCorrelation;
7227 Cost *indexStartupCost,
Cost *indexTotalCost,
7228 Selectivity *indexSelectivity,
double *indexCorrelation,
7234 double numIndexTuples;
7236 List *indexBoundQuals;
7237 List *indexSkipQuals;
7240 bool found_row_compare;
7242 bool found_is_null_op;
7243 bool have_correlation =
false;
7244 double num_sa_scans;
7245 double correlation = 0.0;
7268 indexBoundQuals =
NIL;
7269 indexSkipQuals =
NIL;
7272 found_row_compare =
false;
7273 found_array =
false;
7274 found_is_null_op =
false;
7281 if (indexcol < iclause->indexcol)
7283 double num_sa_scans_prev_cols = num_sa_scans;
7309 if (found_row_compare)
7324 indexSkipQuals =
NIL;
7328 while (indexcol < iclause->indexcol)
7331 bool isdefault =
true;
7351 have_correlation =
true;
7362 num_sa_scans = num_sa_scans_prev_cols;
7369 if (indexSkipQuals !=
NIL)
7371 List *partialSkipQuals;
7396 num_sa_scans = num_sa_scans_prev_cols;
7401 ndistinct = rint(ndistinct * ndistinctfrac);
7402 ndistinct =
Max(ndistinct, 1);
7423 if (indexSkipQuals ==
NIL)
7434 num_sa_scans *= ndistinct;
7453 if (
index->pages < num_sa_scans)
7455 num_sa_scans = num_sa_scans_prev_cols;
7460 indexSkipQuals =
NIL;
7490 clause_op = op->
opno;
7497 found_row_compare =
true;
7505 clause_op = saop->
opno;
7509 num_sa_scans *= alength;
7517 found_is_null_op =
true;
7523 elog(
ERROR,
"unsupported indexqual type: %d",
7530 index->opfamily[indexcol]);
7531 Assert(op_strategy != 0);
7536 indexBoundQuals =
lappend(indexBoundQuals, rinfo);
7543 if (!eqQualHere && !found_row_compare &&
7544 indexcol < index->nkeycolumns - 1)
7545 indexSkipQuals =
lappend(indexSkipQuals, rinfo);
7555 if (
index->unique &&
7556 indexcol ==
index->nkeycolumns - 1 &&
7560 numIndexTuples = 1.0;
7563 List *selectivityQuals;
7577 numIndexTuples = btreeSelectivity *
index->rel->tuples;
7602 num_sa_scans =
Min(num_sa_scans, ceil(
index->pages * 0.3333333));
7603 num_sa_scans =
Max(num_sa_scans, 1);
7624 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7646 if (
index->tuples > 1)
7668 if (!have_correlation)
7690 Cost *indexStartupCost,
Cost *indexTotalCost,
7691 Selectivity *indexSelectivity,
double *indexCorrelation,
7732 Cost *indexStartupCost,
Cost *indexTotalCost,
7733 Selectivity *indexSelectivity,
double *indexCorrelation,
7751 if (
index->tree_height < 0)
7753 if (
index->pages > 1)
7754 index->tree_height = (int) (log(
index->pages) / log(100.0));
7756 index->tree_height = 0;
7764 if (
index->tuples > 1)
7787 Cost *indexStartupCost,
Cost *indexTotalCost,
7788 Selectivity *indexSelectivity,
double *indexCorrelation,
7806 if (
index->tree_height < 0)
7808 if (
index->pages > 1)
7809 index->tree_height = (int) (log(
index->pages) / log(100.0));
7811 index->tree_height = 0;
7819 if (
index->tuples > 1)
7872 bool *partial_matches = NULL;
7874 bool *nullFlags = NULL;
7878 Assert(indexcol < index->nkeycolumns);
7887 &strategy_op, &lefttype, &righttype);
7895 index->opcintype[indexcol],
7896 index->opcintype[indexcol],
7902 elog(
ERROR,
"missing support function %d for attribute %d of index \"%s\"",
7911 collation =
index->indexcollations[indexcol];
7913 collation = DEFAULT_COLLATION_OID;
7935 for (
i = 0;
i < nentries;
i++)
7941 if (partial_matches && partial_matches[
i])
8003 if (((
Const *) operand)->constisnull)
8008 ((
Const *) operand)->constvalue,
8029 double numIndexEntries,
8042 int numPossible = 0;
8068 if (((
Const *) rightop)->constisnull)
8074 &elmlen, &elmbyval, &elmalign);
8077 elmlen, elmbyval, elmalign,
8078 &elemValues, &elemNulls, &numElems);
8080 memset(&arraycounts, 0,
sizeof(arraycounts));
8082 for (
i = 0;
i < numElems;
i++)
8091 memset(&elemcounts, 0,
sizeof(elemcounts));
8117 if (numPossible == 0)
8142 Cost *indexStartupCost,
Cost *indexTotalCost,
8143 Selectivity *indexSelectivity,
double *indexCorrelation,
8148 List *selectivityQuals;
8149 double numPages =
index->pages,
8150 numTuples =
index->tuples;
8151 double numEntryPages,
8158 double partialScale;
8159 double entryPagesFetched,
8161 dataPagesFetchedBySel;
8162 double qual_op_cost,
8164 spc_random_page_cost,
8176 if (!
index->hypothetical)
8185 memset(&ginStats, 0,
sizeof(ginStats));
8202 numPendingPages = 0;
8204 if (numPages > 0 && ginStats.
nTotalPages <= numPages &&
8219 numEntryPages =
Min(numEntryPages, numPages - numPendingPages);
8220 numDataPages =
Min(numDataPages,
8221 numPages - numPendingPages - numEntryPages);
8238 numPages =
Max(numPages, 10);
8239 numEntryPages = floor((numPages - numPendingPages) * 0.90);
8240 numDataPages = numPages - numPendingPages - numEntryPages;
8241 numEntries = floor(numEntryPages * 100);
8263 &spc_random_page_cost,
8269 *indexCorrelation = 0.0;
8274 memset(&counts, 0,
sizeof(counts));
8276 matchPossible =
true;
8312 elog(
ERROR,
"unsupported GIN indexqual type: %d",
8321 *indexStartupCost = 0;
8322 *indexTotalCost = 0;
8323 *indexSelectivity = 0;
8333 fullIndexScan =
false;
8334 for (
i = 0;
i <
index->nkeycolumns;
i++)
8338 fullIndexScan =
true;
8343 if (fullIndexScan || indexQuals ==
NIL)
8355 outer_scans = loop_count;
8361 entryPagesFetched = numPendingPages;
8370 entryPagesFetched += ceil(counts.
searchEntries * rint(pow(numEntryPages, 0.15)));
8380 partialScale =
Min(partialScale, 1.0);
8382 entryPagesFetched += ceil(numEntryPages * partialScale);
8389 dataPagesFetched = ceil(numDataPages * partialScale);
8391 *indexStartupCost = 0;
8392 *indexTotalCost = 0;
8437 if (outer_scans > 1 || counts.
arrayScans > 1)
8439 entryPagesFetched *= outer_scans * counts.
arrayScans;
8442 numEntryPages,
root);
8443 entryPagesFetched /= outer_scans;
8444 dataPagesFetched *= outer_scans * counts.
arrayScans;
8447 numDataPages,
root);
8448 dataPagesFetched /= outer_scans;
8455 *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
8465 dataPagesFetched = ceil(numDataPages * counts.
exactEntries / numEntries);
8478 dataPagesFetchedBySel = ceil(*indexSelectivity *
8479 (numTuples / (BLCKSZ / 3)));
8480 if (dataPagesFetchedBySel > dataPagesFetched)
8481 dataPagesFetched = dataPagesFetchedBySel;
8493 if (outer_scans > 1 || counts.
arrayScans > 1)
8495 dataPagesFetched *= outer_scans * counts.
arrayScans;
8498 numDataPages,
root);
8499 dataPagesFetched /= outer_scans;
8503 *indexTotalCost += *indexStartupCost +
8504 dataPagesFetched * spc_random_page_cost;
8514 *indexStartupCost += qual_arg_cost;
8515 *indexTotalCost += qual_arg_cost;
8524 *indexPages = dataPagesFetched;
8532 Cost *indexStartupCost,
Cost *indexTotalCost,
8533 Selectivity *indexSelectivity,
double *indexCorrelation,
8538 double numPages =
index->pages;
8541 Cost spc_seq_page_cost;
8542 Cost spc_random_page_cost;
8543 double qual_arg_cost;
8544 double qualSelectivity;
8547 double minimalRanges;
8548 double estimatedRanges;
8558 &spc_random_page_cost,
8559 &spc_seq_page_cost);
8565 if (!
index->hypothetical)
8575 indexRanges =
Max(ceil((
double) baserel->
pages /
8584 indexRanges =
Max(ceil((
double) baserel->
pages /
8599 *indexCorrelation = 0;
8619 "no function provided to release variable stats with");
8650 elog(
ERROR,
"no function provided to release variable stats with");
8670 double varCorrelation = 0.0;
8673 varCorrelation = fabs(sslot.
numbers[0]);
8675 if (varCorrelation > *indexCorrelation)
8676 *indexCorrelation = varCorrelation;
8693 minimalRanges = ceil(indexRanges * qualSelectivity);
8700 if (*indexCorrelation < 1.0e-10)
8701 estimatedRanges = indexRanges;
8703 estimatedRanges =
Min(minimalRanges / *indexCorrelation, indexRanges);
8706 selec = estimatedRanges / indexRanges;
8710 *indexSelectivity = selec;
8725 *indexStartupCost += qual_arg_cost;
8732 *indexTotalCost = *indexStartupCost +
8733 spc_random_page_cost * (numPages - statsData.
revmapNumPages) * loop_count;
8745 *indexPages =
index->pages;
Datum idx(PG_FUNCTION_ARGS)
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(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)
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)
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_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 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 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)
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)
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)
static double eqjoinsel_inner(Oid opfuncoid, Oid collation, 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)
Datum eqsel(PG_FUNCTION_ARGS)
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)
static double eqjoinsel_semi(Oid opfuncoid, Oid collation, 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, RelOptInfo *inner_rel)
void gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
static double convert_timevalue_to_scalar(Datum value, Oid typid, bool *failure)
static double convert_numeric_to_scalar(Datum value, Oid typid, bool *failure)
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)
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)
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)
double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, int min_hist_size, int n_skip, int *hist_size)
Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
static void examine_indexcol_variable(PlannerInfo *root, IndexOptInfo *index, int indexcol, VariableStatData *vardata)
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
Selectivity indexSelectivity
double spc_random_page_cost
bool attHasNormalScan[INDEX_MAX_KEYS]
bool attHasFullScan[INDEX_MAX_KEYS]
BlockNumber nPendingPages
struct TupleDescData * xs_itupdesc
MVNDistinctItem items[FLEXIBLE_ARRAY_MEMBER]
NullTestType nulltesttype
void(* freefunc)(HeapTuple tuple)
#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)
#define VARSIZE_ANY_EXHDR(PTR)
#define VM_ALL_VISIBLE(r, b, v)