131#include "utils/fmgroids.h"
144#define DEFAULT_PAGE_CPU_MULTIPLIER 50.0
153 double nd1,
double nd2,
154 bool isdefault1,
bool isdefault2,
157 bool have_mcvs1,
bool have_mcvs2);
160 double nd1,
double nd2,
161 bool isdefault1,
bool isdefault2,
164 bool have_mcvs1,
bool have_mcvs2,
171 double *scaledlobound,
double *scaledhibound);
176 double *scaledlobound,
178 double *scaledhibound);
182 double *scaledlobound,
184 double *scaledhibound);
186 int rangelo,
int rangehi);
188 int rangelo,
int rangehi);
198 Oid sortop,
Oid collation,
202 Oid collation,
int16 typLen,
bool typByVal,
206 Oid sortop,
Oid collation,
216 Datum *endpointDatum);
271 &vardata, &other, &varonleft))
281 ((
Const *) other)->constvalue,
282 ((
Const *) other)->constisnull,
300 Datum constval,
bool constisnull,
301 bool varonleft,
bool negate)
304 double nullfrac = 0.0;
324 nullfrac = stats->stanullfrac;
370 fcinfo->args[0].isnull =
false;
371 fcinfo->args[1].isnull =
false;
374 fcinfo->args[1].value = constval;
376 fcinfo->args[0].value = constval;
383 fcinfo->args[0].value = sslot.
values[
i];
385 fcinfo->args[1].value = sslot.
values[
i];
386 fcinfo->isnull =
false;
416 double sumcommon = 0.0;
417 double otherdistinct;
421 selec = 1.0 - sumcommon - nullfrac;
431 if (otherdistinct > 1)
432 selec /= otherdistinct;
456 selec = 1.0 - selec - nullfrac;
472 bool varonleft,
bool negate)
475 double nullfrac = 0.0;
486 nullfrac = stats->stanullfrac;
515 selec = 1.0 - nullfrac;
545 selec = 1.0 - selec - nullfrac;
629 if (block >= vardata->
rel->
pages - 1)
644 block +=
Min(offset / density, 1.0);
651 selec = block / (vardata->
rel->
pages - 0.5);
661 if (iseq == isgt && vardata->
rel->
tuples >= 1.0)
685 mcv_selec =
mcv_selectivity(vardata, &opproc, collation, constval,
true,
693 operator, &opproc, isgt, iseq,
695 constval, consttype);
702 selec = 1.0 - stats->stanullfrac - sumcommon;
704 if (hist_selec >= 0.0)
737 Datum constval,
bool varonleft,
765 fcinfo->args[0].isnull =
false;
766 fcinfo->args[1].isnull =
false;
769 fcinfo->args[1].value = constval;
771 fcinfo->args[0].value = constval;
778 fcinfo->args[0].value = sslot.
values[
i];
780 fcinfo->args[1].value = sslot.
values[
i];
781 fcinfo->isnull =
false;
790 *sumcommonp = sumcommon;
829 Datum constval,
bool varonleft,
830 int min_hist_size,
int n_skip,
838 Assert(min_hist_size > 2 * n_skip);
847 if (sslot.
nvalues >= min_hist_size)
863 fcinfo->args[0].isnull =
false;
864 fcinfo->args[1].isnull =
false;
867 fcinfo->args[1].value = constval;
869 fcinfo->args[0].value = constval;
871 for (
i = n_skip;
i < sslot.
nvalues - n_skip;
i++)
876 fcinfo->args[0].value = sslot.
values[
i];
878 fcinfo->args[1].value = sslot.
values[
i];
879 fcinfo->isnull =
false;
884 result = ((double) nmatch) / ((double) (sslot.
nvalues - 2 * n_skip));
920 double default_selectivity)
932 &vardata, &other, &varonleft))
933 return default_selectivity;
940 ((
Const *) other)->constisnull)
949 Datum constval = ((
Const *) other)->constvalue;
977 selec = default_selectivity;
979 else if (hist_size < 100)
986 double hist_weight = hist_size / 100.0;
988 selec = selec * hist_weight +
989 default_selectivity * (1.0 - hist_weight);
995 else if (selec > 0.9999)
1009 selec *= 1.0 - nullfrac - mcvsum;
1015 selec = default_selectivity;
1047 Oid opoid,
FmgrInfo *opproc,
bool isgt,
bool iseq,
1099 bool have_end =
false;
1115 while (lobound < hibound)
1117 int probe = (lobound + hibound) / 2;
1125 if (probe == 0 && sslot.
nvalues > 2)
1147 lobound = probe + 1;
1164 else if (lobound >= sslot.
nvalues)
1175 double eq_selec = 0;
1197 if (
i == 1 || isgt == iseq)
1199 double otherdistinct;
1217 if (otherdistinct > 1)
1218 eq_selec = 1.0 / otherdistinct;
1237 else if (
val <= low)
1239 else if (
val >= high)
1243 binfrac = (
val - low) / (high - low);
1251 if (isnan(binfrac) ||
1252 binfrac < 0.0 || binfrac > 1.0)
1274 histfrac = (double) (
i - 1) + binfrac;
1275 histfrac /= (double) (sslot.
nvalues - 1);
1310 histfrac += eq_selec * (1.0 - binfrac);
1318 histfrac -= eq_selec;
1325 hist_selec = isgt ? (1.0 - histfrac) : histfrac;
1340 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1342 if (hist_selec < cutoff)
1343 hist_selec = cutoff;
1344 else if (hist_selec > 1.0 - cutoff)
1345 hist_selec = 1.0 - cutoff;
1362 fcinfo->args[0].isnull =
false;
1363 fcinfo->args[1].isnull =
false;
1364 fcinfo->args[1].value = constval;
1369 fcinfo->args[0].value = sslot.
values[
i];
1370 fcinfo->isnull =
false;
1375 hist_selec = ((double) nmatch) / ((double) sslot.
nvalues);
1384 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1386 if (hist_selec < cutoff)
1387 hist_selec = cutoff;
1388 else if (hist_selec > 1.0 - cutoff)
1389 hist_selec = 1.0 - cutoff;
1423 &vardata, &other, &varonleft))
1439 if (((
Const *) other)->constisnull)
1444 constval = ((
Const *) other)->constvalue;
1445 consttype = ((
Const *) other)->consttype;
1464 &vardata, constval, consttype);
1570 freq_null = stats->stanullfrac;
1586 freq_true = 1.0 - sslot.
numbers[0] - freq_null;
1592 freq_false = 1.0 - freq_true - freq_null;
1594 switch (booltesttype)
1602 selec = 1.0 - freq_null;
1610 selec = 1.0 - freq_true;
1618 selec = 1.0 - freq_false;
1621 elog(
ERROR,
"unrecognized booltesttype: %d",
1622 (
int) booltesttype);
1636 switch (booltesttype)
1644 selec = 1.0 - freq_null;
1649 selec = (1.0 - freq_null) / 2.0;
1655 selec = (freq_null + 1.0) / 2.0;
1658 elog(
ERROR,
"unrecognized booltesttype: %d",
1659 (
int) booltesttype);
1673 switch (booltesttype)
1694 elog(
ERROR,
"unrecognized booltesttype: %d",
1695 (
int) booltesttype);
1727 freq_null = stats->stanullfrac;
1729 switch (nulltesttype)
1744 selec = 1.0 - freq_null;
1747 elog(
ERROR,
"unrecognized nulltesttype: %d",
1748 (
int) nulltesttype);
1753 ((
Var *) vardata.
var)->varattno < 0)
1759 selec = (nulltesttype ==
IS_NULL) ? 0.0 : 1.0;
1766 switch (nulltesttype)
1775 elog(
ERROR,
"unrecognized nulltesttype: %d",
1776 (
int) nulltesttype);
1833 bool is_join_clause,
1839 bool useOr = clause->
useOr;
1840 bool isEquality =
false;
1841 bool isInequality =
false;
1844 Oid nominal_element_type;
1845 Oid nominal_element_collation;
1878 if (
operator == typentry->
eq_opr)
1881 isInequality =
true;
1890 if ((isEquality || isInequality) && !is_join_clause)
1893 nominal_element_type,
1894 isEquality, useOr, varRelid);
1919 if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
1921 else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
1922 isInequality =
true;
1936 if (rightop &&
IsA(rightop,
Const))
1938 Datum arraydatum = ((
Const *) rightop)->constvalue;
1939 bool arrayisnull = ((
Const *) rightop)->constisnull;
1953 &elmlen, &elmbyval, &elmalign);
1956 elmlen, elmbyval, elmalign,
1957 &elem_values, &elem_nulls, &num_elems);
1973 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
1975 for (
i = 0;
i < num_elems;
i++)
1983 nominal_element_collation,
1990 clause->inputcollid,
1998 clause->inputcollid,
2014 s1disjoint +=
s2 - 1.0;
2019 if ((useOr ? isEquality : isInequality) &&
2020 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2032 &elmlen, &elmbyval);
2041 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2043 foreach(l, arrayexpr->elements)
2057 clause->inputcollid,
2065 clause->inputcollid,
2081 s1disjoint +=
s2 - 1.0;
2086 if ((useOr ? isEquality : isInequality) &&
2087 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2103 dummyexpr->
typeId = nominal_element_type;
2104 dummyexpr->typeMod = -1;
2105 dummyexpr->collation = clause->inputcollid;
2109 clause->inputcollid,
2117 clause->inputcollid,
2122 s1 = useOr ? 0.0 : 1.0;
2129 for (
i = 0;
i < 10;
i++)
2159 if (arrayexpr &&
IsA(arrayexpr,
Const))
2161 Datum arraydatum = ((
Const *) arrayexpr)->constvalue;
2162 bool arrayisnull = ((
Const *) arrayexpr)->constisnull;
2175 else if (arrayexpr &&
root)
2228 bool is_join_clause;
2244 is_join_clause =
false;
2246 else if (sjinfo == NULL)
2252 is_join_clause =
false;
2311 bool have_mcvs1 =
false;
2312 bool have_mcvs2 =
false;
2314 bool join_is_reversed;
2318 &vardata1, &vardata2, &join_is_reversed);
2325 memset(&sslot1, 0,
sizeof(sslot1));
2326 memset(&sslot2, 0,
sizeof(sslot2));
2345 if (get_mcv_stats &&
2356 if (get_mcv_stats &&
2365 &vardata1, &vardata2,
2367 isdefault1, isdefault2,
2370 have_mcvs1, have_mcvs2);
2377 selec = selec_inner;
2390 if (!join_is_reversed)
2392 &vardata1, &vardata2,
2394 isdefault1, isdefault2,
2397 have_mcvs1, have_mcvs2,
2405 &vardata2, &vardata1,
2407 isdefault2, isdefault1,
2410 have_mcvs2, have_mcvs1,
2424 selec =
Min(selec, inner_rel->
rows * selec_inner);
2428 elog(
ERROR,
"unrecognized join type: %d",
2454 double nd1,
double nd2,
2455 bool isdefault1,
bool isdefault2,
2458 bool have_mcvs1,
bool have_mcvs2)
2462 if (have_mcvs1 && have_mcvs2)
2480 double nullfrac1 = stats1->stanullfrac;
2481 double nullfrac2 = stats2->stanullfrac;
2482 double matchprodfreq,
2504 fcinfo->args[0].isnull =
false;
2505 fcinfo->args[1].isnull =
false;
2516 matchprodfreq = 0.0;
2522 fcinfo->args[0].value = sslot1->
values[
i];
2530 fcinfo->args[1].value = sslot2->
values[
j];
2531 fcinfo->isnull =
false;
2535 hasmatch1[
i] = hasmatch2[
j] =
true;
2544 matchfreq1 = unmatchfreq1 = 0.0;
2550 unmatchfreq1 += sslot1->
numbers[
i];
2554 matchfreq2 = unmatchfreq2 = 0.0;
2560 unmatchfreq2 += sslot2->
numbers[
i];
2571 otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
2572 otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
2584 totalsel1 = matchprodfreq;
2586 totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->
nvalues);
2588 totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
2591 totalsel2 = matchprodfreq;
2593 totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->
nvalues);
2595 totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
2604 selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
2628 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2629 double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
2631 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
2651 double nd1,
double nd2,
2652 bool isdefault1,
bool isdefault2,
2655 bool have_mcvs1,
bool have_mcvs2,
2681 if (nd2 >= vardata2->
rel->
rows)
2687 if (nd2 >= inner_rel->
rows)
2689 nd2 = inner_rel->
rows;
2693 if (have_mcvs1 && have_mcvs2 &&
OidIsValid(opfuncoid))
2707 double nullfrac1 = stats1->stanullfrac;
2722 clamped_nvalues2 =
Min(sslot2->
nvalues, nd2);
2734 fcinfo->args[0].isnull =
false;
2735 fcinfo->args[1].isnull =
false;
2738 hasmatch2 = (
bool *)
palloc0(clamped_nvalues2 *
sizeof(
bool));
2751 fcinfo->args[0].value = sslot1->
values[
i];
2753 for (
j = 0;
j < clamped_nvalues2;
j++)
2759 fcinfo->args[1].value = sslot2->
values[
j];
2760 fcinfo->isnull =
false;
2764 hasmatch1[
i] = hasmatch2[
j] =
true;
2796 if (!isdefault1 && !isdefault2)
2800 if (nd1 <= nd2 || nd2 < 0)
2801 uncertainfrac = 1.0;
2803 uncertainfrac = nd2 / nd1;
2806 uncertainfrac = 0.5;
2807 uncertain = 1.0 - matchfreq1 - nullfrac1;
2809 selec = matchfreq1 + uncertainfrac * uncertain;
2817 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2819 if (!isdefault1 && !isdefault2)
2821 if (nd1 <= nd2 || nd2 < 0)
2822 selec = 1.0 - nullfrac1;
2824 selec = (nd2 / nd1) * (1.0 - nullfrac1);
2827 selec = 0.5 * (1.0 - nullfrac1);
2879 result = 1.0 - nullfrac;
2905 result = 1.0 - result;
3006 *leftstart = *rightstart = 0.0;
3007 *leftend = *rightend = 1.0;
3012 opno = ((
OpExpr *) clause)->opno;
3013 collation = ((
OpExpr *) clause)->inputcollid;
3045 if (op_lefttype == op_righttype)
3049 op_lefttype, op_righttype,
3052 op_lefttype, op_righttype,
3064 op_lefttype, op_righttype,
3067 op_lefttype, op_righttype,
3070 op_lefttype, op_lefttype,
3073 op_righttype, op_righttype,
3078 op_righttype, op_lefttype,
3081 op_righttype, op_lefttype,
3091 if (op_lefttype == op_righttype)
3095 op_lefttype, op_righttype,
3098 op_lefttype, op_righttype,
3103 op_lefttype, op_lefttype,
3112 op_lefttype, op_righttype,
3115 op_lefttype, op_righttype,
3118 op_lefttype, op_lefttype,
3121 op_righttype, op_righttype,
3124 op_lefttype, op_lefttype,
3127 op_righttype, op_righttype,
3130 op_righttype, op_lefttype,
3133 op_righttype, op_lefttype,
3155 &leftmin, &leftmax))
3158 &rightmin, &rightmax))
3165 &leftmax, &leftmin))
3168 &rightmax, &rightmin))
3178 rightmax, op_righttype);
3184 leftmax, op_lefttype);
3194 if (*leftend > *rightend)
3196 else if (*leftend < *rightend)
3199 *leftend = *rightend = 1.0;
3208 rightmin, op_righttype);
3214 leftmin, op_lefttype);
3216 *rightstart = selec;
3224 if (*leftstart < *rightstart)
3226 else if (*leftstart > *rightstart)
3229 *leftstart = *rightstart = 0.0;
3244 *leftstart += stats->stanullfrac;
3246 *leftend += stats->stanullfrac;
3252 *rightstart += stats->stanullfrac;
3254 *rightend += stats->stanullfrac;
3260 if (*leftstart >= *leftend)
3265 if (*rightstart >= *rightend)
3345 foreach(lc, varinfos)
3358 if (vardata->
rel != varinfo->
rel &&
3377 varinfo->
rel = vardata->
rel;
3380 varinfos =
lappend(varinfos, varinfo);
3460 double srf_multiplier = 1.0;
3466 if (estinfo != NULL)
3482 if (groupExprs ==
NIL || (pgset && *pgset ==
NIL))
3495 foreach(l, groupExprs)
3498 double this_srf_multiplier;
3519 if (srf_multiplier < this_srf_multiplier)
3520 srf_multiplier = this_srf_multiplier;
3523 if (
exprType(groupexpr) == BOOLOID)
3546 groupexpr, &vardata);
3569 if (varshere ==
NIL)
3579 foreach(l2, varshere)
3593 if (varinfos ==
NIL)
3596 numdistinct *= srf_multiplier;
3598 numdistinct = ceil(numdistinct);
3600 if (numdistinct > input_rows)
3601 numdistinct = input_rows;
3602 if (numdistinct < 1.0)
3619 double reldistinct = 1;
3620 double relmaxndistinct = reldistinct;
3621 int relvarcount = 0;
3629 relvarinfos =
lappend(relvarinfos, varinfo1);
3634 if (varinfo2->
rel == varinfo1->
rel)
3637 relvarinfos =
lappend(relvarinfos, varinfo2);
3642 newvarinfos =
lappend(newvarinfos, varinfo2);
3665 reldistinct *= mvndistinct;
3666 if (relmaxndistinct < mvndistinct)
3667 relmaxndistinct = mvndistinct;
3672 foreach(l, relvarinfos)
3677 if (relmaxndistinct < varinfo2->ndistinct)
3685 if (estinfo != NULL && varinfo2->
isdefault)
3707 double clamp = rel->
tuples;
3709 if (relvarcount > 1)
3712 if (clamp < relmaxndistinct)
3714 clamp = relmaxndistinct;
3720 if (reldistinct > clamp)
3721 reldistinct = clamp;
3728 if (reldistinct > 0 && rel->
rows < rel->
tuples)
3766 rel->
tuples / reldistinct));
3773 numdistinct *= reldistinct;
3776 varinfos = newvarinfos;
3777 }
while (varinfos !=
NIL);
3780 numdistinct *= srf_multiplier;
3783 numdistinct = ceil(numdistinct);
3786 if (numdistinct > input_rows)
3787 numdistinct = input_rows;
3788 if (numdistinct < 1.0)
3831 while (clauses !=
NIL)
3838 List *origin_varinfos;
3839 int group_relid = -1;
3850 foreach(lc, clauses)
3862 relids = rinfo->outer_is_left ?
3863 rinfo->right_relids : rinfo->left_relids;
3864 expr = rinfo->outer_is_left ?
3868 root->simple_rel_array[relid]->statlist !=
NIL)
3870 bool is_duplicate =
false;
3876 if (group_relid < 0)
3880 if (!rte || (rte->relkind != RELKIND_RELATION &&
3881 rte->relkind != RELKIND_MATVIEW &&
3882 rte->relkind != RELKIND_FOREIGN_TABLE &&
3883 rte->relkind != RELKIND_PARTITIONED_TABLE))
3886 otherclauses =
lappend(otherclauses, rinfo);
3891 group_relid = relid;
3892 group_rel =
root->simple_rel_array[relid];
3894 else if (group_relid != relid)
3930 foreach(lc1, varinfos)
3937 is_duplicate =
true;
3956 varinfo->
var = expr;
3957 varinfo->
rel =
root->simple_rel_array[relid];
3958 varinfos =
lappend(varinfos, varinfo);
3964 origin_rinfos =
lappend(origin_rinfos, rinfo);
3969 otherclauses =
lappend(otherclauses, rinfo);
3981 otherclauses =
list_concat(otherclauses, origin_rinfos);
3987 Assert(group_rel != NULL);
3990 origin_varinfos = varinfos;
4006 if (ndistinct < mvndistinct)
4007 ndistinct = mvndistinct;
4008 Assert(ndistinct >= 1.0);
4014 forboth(lc1, origin_varinfos, lc2, origin_rinfos)
4027 *innerbucketsize = 1.0 / ndistinct;
4028 return otherclauses;
4127 stanullfrac = stats->stanullfrac;
4133 avgfreq = (1.0 - stanullfrac) / ndistinct;
4154 if (ndistinct > nbuckets)
4155 estfract = 1.0 / nbuckets;
4157 estfract = 1.0 / ndistinct;
4162 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
4163 estfract *= *mcv_freq / avgfreq;
4170 if (estfract < 1.0e-6)
4172 else if (estfract > 1.0)
4200 path->pathtarget->width,
4209 return hashentrysize * dNumGroups;
4236 List **varinfos,
double *ndistinct)
4257 int nshared_vars = 0;
4258 int nshared_exprs = 0;
4261 if (info->
kind != STATS_EXT_NDISTINCT)
4273 foreach(lc2, *varinfos)
4301 foreach(lc3, info->
exprs)
4319 if (nshared_vars + nshared_exprs < 2)
4330 if ((nshared_exprs > nmatches_exprs) ||
4331 (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
4334 nmatches_vars = nshared_vars;
4335 nmatches_exprs = nshared_exprs;
4336 matched_info = info;
4344 Assert(nmatches_vars + nmatches_exprs > 1);
4366 if (matched_info->
exprs)
4372 foreach(lc2, *varinfos)
4420 foreach(lc3, matched_info->
exprs)
4487 elog(
ERROR,
"corrupt MVNDistinct entry");
4490 foreach(lc, *varinfos)
4512 newlist =
lappend(newlist, varinfo);
4521 newlist =
lappend(newlist, varinfo);
4537 foreach(lc3, matched_info->
exprs)
4552 newlist =
lappend(newlist, varinfo);
4555 *varinfos = newlist;
4595 double *scaledlobound,
double *scaledhibound)
4597 bool failure =
false;
4631 case REGPROCEDUREOID:
4633 case REGOPERATOROID:
4636 case REGCOLLATIONOID:
4638 case REGDICTIONARYOID:
4640 case REGNAMESPACEOID:
4641 case REGDATABASEOID:
4675 lostr, scaledlobound,
4676 histr, scaledhibound);
4689 if (boundstypid != BYTEAOID)
4692 lobound, scaledlobound,
4693 hibound, scaledhibound);
4701 case TIMESTAMPTZOID:
4730 *scaledvalue = *scaledlobound = *scaledhibound = 0;
4764 case REGPROCEDUREOID:
4766 case REGOPERATOROID:
4769 case REGCOLLATIONOID:
4771 case REGDICTIONARYOID:
4773 case REGNAMESPACEOID:
4774 case REGDATABASEOID:
4805 double *scaledvalue,
4807 double *scaledlobound,
4809 double *scaledhibound)
4815 rangelo = rangehi = (
unsigned char) hibound[0];
4816 for (sptr = lobound; *sptr; sptr++)
4818 if (rangelo > (
unsigned char) *sptr)
4819 rangelo = (
unsigned char) *sptr;
4820 if (rangehi < (
unsigned char) *sptr)
4821 rangehi = (
unsigned char) *sptr;
4823 for (sptr = hibound; *sptr; sptr++)
4825 if (rangelo > (
unsigned char) *sptr)
4826 rangelo = (
unsigned char) *sptr;
4827 if (rangehi < (
unsigned char) *sptr)
4828 rangehi = (
unsigned char) *sptr;
4831 if (rangelo <= 'Z' && rangehi >=
'A')
4839 if (rangelo <= 'z' && rangehi >=
'a')
4847 if (rangelo <= '9' && rangehi >=
'0')
4859 if (rangehi - rangelo < 9)
4870 if (*lobound != *hibound || *lobound != *
value)
4872 lobound++, hibound++,
value++;
4886 int slen = strlen(
value);
4907 base = rangehi - rangelo + 1;
4912 int ch = (
unsigned char) *
value++;
4916 else if (ch > rangehi)
4918 num += ((double) (ch - rangelo)) / denom;
4993 if (xfrmlen == INT_MAX)
4996 xfrmstr = (
char *)
palloc(xfrmlen + 1);
5003 Assert(xfrmlen2 <= xfrmlen);
5024 double *scaledvalue,
5026 double *scaledlobound,
5028 double *scaledhibound)
5040 unsigned char *valstr = (
unsigned char *)
VARDATA_ANY(valuep);
5041 unsigned char *lostr = (
unsigned char *)
VARDATA_ANY(loboundp);
5042 unsigned char *histr = (
unsigned char *)
VARDATA_ANY(hiboundp);
5053 minlen =
Min(
Min(valuelen, loboundlen), hiboundlen);
5054 for (
i = 0;
i < minlen;
i++)
5056 if (*lostr != *histr || *lostr != *valstr)
5058 lostr++, histr++, valstr++;
5059 loboundlen--, hiboundlen--, valuelen--;
5072 int rangelo,
int rangehi)
5089 base = rangehi - rangelo + 1;
5092 while (valuelen-- > 0)
5098 else if (ch > rangehi)
5100 num += ((double) (ch - rangelo)) / denom;
5120 case TIMESTAMPTZOID:
5147 return (
double) (timetz->
time + (timetz->
zone * 1000000.0));
5205 if (vardata->
rel && rdata.
rel == NULL)
5213 if (vardata->
rel == NULL && rdata.
rel)
5242 bool *join_is_reversed)
5248 elog(
ERROR,
"join operator should take two arguments");
5256 if (vardata1->
rel &&
5258 *join_is_reversed =
true;
5259 else if (vardata2->
rel &&
5261 *join_is_reversed =
true;
5263 *join_is_reversed =
false;
5332 if (
IsA(basenode,
Var) &&
5333 (varRelid == 0 || varRelid == ((
Var *) basenode)->varno))
5335 Var *var = (
Var *) basenode;
5338 vardata->
var = basenode;
5340 vardata->
atttype = var->vartype;
5371 if (varRelid == 0 || varRelid == relid)
5374 vardata->
rel = onerel;
5401 vardata->
var = node;
5438 if (indexpr_item == NULL)
5441 for (pos = 0; pos <
index->ncolumns; pos++)
5443 if (
index->indexkeys[pos] == 0)
5447 if (indexpr_item == NULL)
5448 elog(
ERROR,
"too few entries in indexprs list");
5452 if (
equal(node, indexkey))
5458 if (
index->unique &&
5459 index->nkeycolumns == 1 &&
5485 elog(
ERROR,
"no function provided to release variable stats with");
5534 indexpr_item =
lnext(
index->indexprs, indexpr_item);
5562 if (info->
kind != STATS_EXT_EXPRESSIONS)
5570 foreach(expr_item, info->
exprs)
5581 if (
equal(node, expr))
5651 elog(
ERROR,
"no function provided to release variable stats with");
5742 while (levelsup-- > 0)
5744 cteroot = cteroot->parent_root;
5774 if (subroot == NULL)
5785 subquery = subroot->
parse;
5806 if (ste == NULL || ste->resjunk)
5807 elog(
ERROR,
"subquery %s does not have attribute %d",
5808 rte->eref->aliasname, var->
varattno);
5849 if (rte->security_barrier)
5853 if (var &&
IsA(var,
Var) &&
5952 if (
root->append_rel_array != NULL)
5956 appinfo =
root->append_rel_array[varno];
5992 parent_attno = appinfo->parent_colnos[attno - 1];
5993 if (parent_attno == 0)
6005 parent_attno = attno;
6011 parent_attno = appinfo->parent_colnos[attno - 1];
6012 if (parent_attno == 0)
6023 varattnos = parent_varattnos;
6024 appinfo =
root->append_rel_array[varno];
6036 if (rte->securityQuals !=
NIL)
6054 if (varattnos == NULL)
6112 if (
index->indexkeys[indexcol] != 0)
6120 colnum =
index->indexkeys[indexcol];
6132 elog(
ERROR,
"no function provided to release variable stats with");
6146 relid =
index->indexoid;
6147 colnum = indexcol + 1;
6158 elog(
ERROR,
"no function provided to release variable stats with");
6192 (
errmsg_internal(
"not using statistics because function \"%s\" is not leakproof",
6212 double stanullfrac = 0.0;
6229 stadistinct = stats->stadistinct;
6230 stanullfrac = stats->stanullfrac;
6232 else if (vardata->
vartype == BOOLOID)
6261 switch (((
Var *) vardata->
var)->varattno)
6290 stadistinct = -1.0 * (1.0 - stanullfrac);
6295 if (stadistinct > 0.0)
6301 if (vardata->
rel == NULL)
6316 if (stadistinct < 0.0)
6343 Oid sortop,
Oid collation,
6348 bool have_data =
false;
6393 STATISTIC_KIND_HISTOGRAM, sortop,
6417 collation, typLen, typByVal,
6418 &tmin, &tmax, &have_data);
6435 bool use_mcvs = have_data;
6439 double sumcommon = 0.0;
6446 if (sumcommon + nullfrac > 0.99999)
6452 collation, typLen, typByVal,
6453 &tmin, &tmax, &have_data);
6470 Oid collation,
int16 typLen,
bool typByVal,
6475 bool have_data = *p_have_data;
6476 bool found_tmin =
false;
6477 bool found_tmax =
false;
6480 if (opproc->
fn_oid != opfuncoid)
6488 tmin = tmax = sslot->
values[
i];
6489 found_tmin = found_tmax =
true;
6490 *p_have_data = have_data =
true;
6513 *min =
datumCopy(tmin, typByVal, typLen);
6515 *max =
datumCopy(tmax, typByVal, typLen);
6533 Oid sortop,
Oid collation,
6536 bool have_data =
false;
6545 rte =
root->simple_rte_array[rel->
relid];
6549 if (rte->relkind == RELKIND_PARTITIONED_TABLE)
6560 if (
index->sortopfamily == NULL)
6574 if (
index->hypothetical)
6581 if (collation !=
index->indexcollations[0])
6589 if (
index->reverse_sort[0])
6595 if (
index->reverse_sort[0])
6621 "get_actual_variable_range workspace",
6666 if (max && have_data)
6722 Datum *endpointDatum)
6724 bool have_data =
false;
6729 int n_visited_heap_pages = 0;
6783 &SnapshotNonVacuumable, NULL,
6811#define VISITED_PAGES_LIMIT 100
6813 if (block != last_heap_block)
6815 last_heap_block = block;
6816 n_visited_heap_pages++;
6838 elog(
ERROR,
"no data returned for index-only scan");
6853 elog(
ERROR,
"found unexpected null value in index \"%s\"",
6894 elog(
ERROR,
"could not find RelOptInfo for given relids");
6916 foreach(lc, indexclauses)
6925 result =
lappend(result, rinfo);
6943 Cost qual_arg_cost = 0;
6946 foreach(lc, indexquals)
6949 Node *other_operand;
6979 other_operand = NULL;
6983 elog(
ERROR,
"unsupported indexqual type: %d",
6985 other_operand = NULL;
6991 return qual_arg_cost;
7003 Cost indexStartupCost;
7004 Cost indexTotalCost;
7006 double indexCorrelation;
7007 double numIndexPages;
7008 double numIndexTuples;
7009 double spc_random_page_cost;
7010 double num_sa_scans;
7011 double num_outer_scans;
7013 double qual_op_cost;
7014 double qual_arg_cost;
7015 List *selectivityQuals;
7031 if (num_sa_scans < 1)
7034 foreach(l, indexQuals)
7044 num_sa_scans *= alength;
7061 if (numIndexTuples <= 0.0)
7063 numIndexTuples = indexSelectivity *
index->rel->tuples;
7072 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7080 if (numIndexTuples >
index->tuples)
7081 numIndexTuples =
index->tuples;
7082 if (numIndexTuples < 1.0)
7083 numIndexTuples = 1.0;
7098 numIndexPages = ceil(numIndexTuples *
index->pages /
index->tuples);
7100 numIndexPages = 1.0;
7104 &spc_random_page_cost,
7124 num_outer_scans = loop_count;
7125 num_scans = num_sa_scans * num_outer_scans;
7129 double pages_fetched;
7132 pages_fetched = numIndexPages * num_scans;
7137 (
double)
index->pages,
7145 indexTotalCost = (pages_fetched * spc_random_page_cost)
7154 indexTotalCost = numIndexPages * spc_random_page_cost;
7176 indexStartupCost = qual_arg_cost;
7177 indexTotalCost += qual_arg_cost;
7183 indexCorrelation = 0.0;
7226 foreach(lc,
index->indpred)
7232 predExtraQuals =
list_concat(predExtraQuals, oneQual);
7253 double indexCorrelation = 0;
7258 index->opcintype[0],
7259 index->opcintype[0],
7263 STATISTIC_KIND_CORRELATION, sortop,
7266 double varCorrelation;
7269 varCorrelation = sslot.
numbers[0];
7271 if (
index->reverse_sort[0])
7272 varCorrelation = -varCorrelation;
7274 if (
index->nkeycolumns > 1)
7275 indexCorrelation = varCorrelation * 0.75;
7277 indexCorrelation = varCorrelation;
7282 return indexCorrelation;
7287 Cost *indexStartupCost,
Cost *indexTotalCost,
7288 Selectivity *indexSelectivity,
double *indexCorrelation,
7294 double numIndexTuples;
7296 List *indexBoundQuals;
7297 List *indexSkipQuals;
7300 bool found_row_compare;
7302 bool found_is_null_op;
7303 bool have_correlation =
false;
7304 double num_sa_scans;
7305 double correlation = 0.0;
7328 indexBoundQuals =
NIL;
7329 indexSkipQuals =
NIL;
7332 found_row_compare =
false;
7333 found_array =
false;
7334 found_is_null_op =
false;
7341 if (indexcol < iclause->indexcol)
7343 double num_sa_scans_prev_cols = num_sa_scans;
7369 if (found_row_compare)
7384 indexSkipQuals =
NIL;
7388 while (indexcol < iclause->indexcol)
7391 bool isdefault =
true;
7411 have_correlation =
true;
7422 num_sa_scans = num_sa_scans_prev_cols;
7429 if (indexSkipQuals !=
NIL)
7431 List *partialSkipQuals;
7456 num_sa_scans = num_sa_scans_prev_cols;
7461 ndistinct = rint(ndistinct * ndistinctfrac);
7462 ndistinct =
Max(ndistinct, 1);
7483 if (indexSkipQuals ==
NIL)
7494 num_sa_scans *= ndistinct;
7513 if (
index->pages < num_sa_scans)
7515 num_sa_scans = num_sa_scans_prev_cols;
7520 indexSkipQuals =
NIL;
7550 clause_op = op->
opno;
7557 found_row_compare =
true;
7565 clause_op = saop->
opno;
7569 num_sa_scans *= alength;
7577 found_is_null_op =
true;
7583 elog(
ERROR,
"unsupported indexqual type: %d",
7590 index->opfamily[indexcol]);
7591 Assert(op_strategy != 0);
7596 indexBoundQuals =
lappend(indexBoundQuals, rinfo);
7603 if (!eqQualHere && !found_row_compare &&
7604 indexcol < index->nkeycolumns - 1)
7605 indexSkipQuals =
lappend(indexSkipQuals, rinfo);
7615 if (
index->unique &&
7616 indexcol ==
index->nkeycolumns - 1 &&
7620 numIndexTuples = 1.0;
7623 List *selectivityQuals;
7637 numIndexTuples = btreeSelectivity *
index->rel->tuples;
7662 num_sa_scans =
Min(num_sa_scans, ceil(
index->pages * 0.3333333));
7663 num_sa_scans =
Max(num_sa_scans, 1);
7684 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7706 if (
index->tuples > 1)
7728 if (!have_correlation)
7750 Cost *indexStartupCost,
Cost *indexTotalCost,
7751 Selectivity *indexSelectivity,
double *indexCorrelation,
7792 Cost *indexStartupCost,
Cost *indexTotalCost,
7793 Selectivity *indexSelectivity,
double *indexCorrelation,
7811 if (
index->tree_height < 0)
7813 if (
index->pages > 1)
7814 index->tree_height = (int) (log(
index->pages) / log(100.0));
7816 index->tree_height = 0;
7824 if (
index->tuples > 1)
7847 Cost *indexStartupCost,
Cost *indexTotalCost,
7848 Selectivity *indexSelectivity,
double *indexCorrelation,
7866 if (
index->tree_height < 0)
7868 if (
index->pages > 1)
7869 index->tree_height = (int) (log(
index->pages) / log(100.0));
7871 index->tree_height = 0;
7879 if (
index->tuples > 1)
7932 bool *partial_matches = NULL;
7934 bool *nullFlags = NULL;
7938 Assert(indexcol < index->nkeycolumns);
7947 &strategy_op, &lefttype, &righttype);
7955 index->opcintype[indexcol],
7956 index->opcintype[indexcol],
7962 elog(
ERROR,
"missing support function %d for attribute %d of index \"%s\"",
7971 collation =
index->indexcollations[indexcol];
7973 collation = DEFAULT_COLLATION_OID;
7995 for (
i = 0;
i < nentries;
i++)
8001 if (partial_matches && partial_matches[
i])
8063 if (((
Const *) operand)->constisnull)
8068 ((
Const *) operand)->constvalue,
8089 double numIndexEntries,
8102 int numPossible = 0;
8128 if (((
Const *) rightop)->constisnull)
8134 &elmlen, &elmbyval, &elmalign);
8137 elmlen, elmbyval, elmalign,
8138 &elemValues, &elemNulls, &numElems);
8140 memset(&arraycounts, 0,
sizeof(arraycounts));
8142 for (
i = 0;
i < numElems;
i++)
8151 memset(&elemcounts, 0,
sizeof(elemcounts));
8177 if (numPossible == 0)
8202 Cost *indexStartupCost,
Cost *indexTotalCost,
8203 Selectivity *indexSelectivity,
double *indexCorrelation,
8208 List *selectivityQuals;
8209 double numPages =
index->pages,
8210 numTuples =
index->tuples;
8211 double numEntryPages,
8218 double partialScale;
8219 double entryPagesFetched,
8221 dataPagesFetchedBySel;
8222 double qual_op_cost,
8224 spc_random_page_cost,
8236 if (!
index->hypothetical)
8245 memset(&ginStats, 0,
sizeof(ginStats));
8262 numPendingPages = 0;
8264 if (numPages > 0 && ginStats.
nTotalPages <= numPages &&
8279 numEntryPages =
Min(numEntryPages, numPages - numPendingPages);
8280 numDataPages =
Min(numDataPages,
8281 numPages - numPendingPages - numEntryPages);
8298 numPages =
Max(numPages, 10);
8299 numEntryPages = floor((numPages - numPendingPages) * 0.90);
8300 numDataPages = numPages - numPendingPages - numEntryPages;
8301 numEntries = floor(numEntryPages * 100);
8323 &spc_random_page_cost,
8329 *indexCorrelation = 0.0;
8334 memset(&counts, 0,
sizeof(counts));
8336 matchPossible =
true;
8372 elog(
ERROR,
"unsupported GIN indexqual type: %d",
8381 *indexStartupCost = 0;
8382 *indexTotalCost = 0;
8383 *indexSelectivity = 0;
8393 fullIndexScan =
false;
8394 for (
i = 0;
i <
index->nkeycolumns;
i++)
8398 fullIndexScan =
true;
8403 if (fullIndexScan || indexQuals ==
NIL)
8415 outer_scans = loop_count;
8421 entryPagesFetched = numPendingPages;
8430 entryPagesFetched += ceil(counts.
searchEntries * rint(pow(numEntryPages, 0.15)));
8440 partialScale =
Min(partialScale, 1.0);
8442 entryPagesFetched += ceil(numEntryPages * partialScale);
8449 dataPagesFetched = ceil(numDataPages * partialScale);
8451 *indexStartupCost = 0;
8452 *indexTotalCost = 0;
8497 if (outer_scans > 1 || counts.
arrayScans > 1)
8499 entryPagesFetched *= outer_scans * counts.
arrayScans;
8502 numEntryPages,
root);
8503 entryPagesFetched /= outer_scans;
8504 dataPagesFetched *= outer_scans * counts.
arrayScans;
8507 numDataPages,
root);
8508 dataPagesFetched /= outer_scans;
8515 *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
8525 dataPagesFetched = ceil(numDataPages * counts.
exactEntries / numEntries);
8538 dataPagesFetchedBySel = ceil(*indexSelectivity *
8539 (numTuples / (BLCKSZ / 3)));
8540 if (dataPagesFetchedBySel > dataPagesFetched)
8541 dataPagesFetched = dataPagesFetchedBySel;
8553 if (outer_scans > 1 || counts.
arrayScans > 1)
8555 dataPagesFetched *= outer_scans * counts.
arrayScans;
8558 numDataPages,
root);
8559 dataPagesFetched /= outer_scans;
8563 *indexTotalCost += *indexStartupCost +
8564 dataPagesFetched * spc_random_page_cost;
8574 *indexStartupCost += qual_arg_cost;
8575 *indexTotalCost += qual_arg_cost;
8584 *indexPages = dataPagesFetched;
8592 Cost *indexStartupCost,
Cost *indexTotalCost,
8593 Selectivity *indexSelectivity,
double *indexCorrelation,
8598 double numPages =
index->pages;
8601 Cost spc_seq_page_cost;
8602 Cost spc_random_page_cost;
8603 double qual_arg_cost;
8604 double qualSelectivity;
8607 double minimalRanges;
8608 double estimatedRanges;
8618 &spc_random_page_cost,
8619 &spc_seq_page_cost);
8625 if (!
index->hypothetical)
8635 indexRanges =
Max(ceil((
double) baserel->
pages /
8644 indexRanges =
Max(ceil((
double) baserel->
pages /
8659 *indexCorrelation = 0;
8679 "no function provided to release variable stats with");
8710 elog(
ERROR,
"no function provided to release variable stats with");
8730 double varCorrelation = 0.0;
8733 varCorrelation = fabs(sslot.
numbers[0]);
8735 if (varCorrelation > *indexCorrelation)
8736 *indexCorrelation = varCorrelation;
8753 minimalRanges = ceil(indexRanges * qualSelectivity);
8760 if (*indexCorrelation < 1.0e-10)
8761 estimatedRanges = indexRanges;
8763 estimatedRanges =
Min(minimalRanges / *indexCorrelation, indexRanges);
8766 selec = estimatedRanges / indexRanges;
8770 *indexSelectivity = selec;
8785 *indexStartupCost += qual_arg_cost;
8792 *indexTotalCost = *indexStartupCost +
8793 spc_random_page_cost * (numPages - statsData.
revmapNumPages) * loop_count;
8805 *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(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)
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 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 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)
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 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)