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);
196 Oid sortop,
Oid collation,
200 Oid collation,
int16 typLen,
bool typByVal,
204 Oid sortop,
Oid collation,
214 Datum *endpointDatum);
267 &vardata, &other, &varonleft))
277 ((
Const *) other)->constvalue,
278 ((
Const *) other)->constisnull,
296 Datum constval,
bool constisnull,
297 bool varonleft,
bool negate)
300 double nullfrac = 0.0;
320 nullfrac = stats->stanullfrac;
366 fcinfo->args[0].isnull =
false;
367 fcinfo->args[1].isnull =
false;
370 fcinfo->args[1].value = constval;
372 fcinfo->args[0].value = constval;
379 fcinfo->args[0].value = sslot.
values[
i];
381 fcinfo->args[1].value = sslot.
values[
i];
382 fcinfo->isnull =
false;
412 double sumcommon = 0.0;
413 double otherdistinct;
417 selec = 1.0 - sumcommon - nullfrac;
427 if (otherdistinct > 1)
428 selec /= otherdistinct;
452 selec = 1.0 - selec - nullfrac;
468 bool varonleft,
bool negate)
471 double nullfrac = 0.0;
482 nullfrac = stats->stanullfrac;
511 selec = 1.0 - nullfrac;
541 selec = 1.0 - selec - nullfrac;
625 if (block >= vardata->
rel->
pages - 1)
640 block +=
Min(offset / density, 1.0);
647 selec = block / (vardata->
rel->
pages - 0.5);
657 if (iseq == isgt && vardata->
rel->
tuples >= 1.0)
681 mcv_selec =
mcv_selectivity(vardata, &opproc, collation, constval,
true,
689 operator, &opproc, isgt, iseq,
691 constval, consttype);
698 selec = 1.0 - stats->stanullfrac - sumcommon;
700 if (hist_selec >= 0.0)
733 Datum constval,
bool varonleft,
761 fcinfo->args[0].isnull =
false;
762 fcinfo->args[1].isnull =
false;
765 fcinfo->args[1].value = constval;
767 fcinfo->args[0].value = constval;
774 fcinfo->args[0].value = sslot.
values[
i];
776 fcinfo->args[1].value = sslot.
values[
i];
777 fcinfo->isnull =
false;
786 *sumcommonp = sumcommon;
825 Datum constval,
bool varonleft,
826 int min_hist_size,
int n_skip,
834 Assert(min_hist_size > 2 * n_skip);
843 if (sslot.
nvalues >= min_hist_size)
859 fcinfo->args[0].isnull =
false;
860 fcinfo->args[1].isnull =
false;
863 fcinfo->args[1].value = constval;
865 fcinfo->args[0].value = constval;
867 for (
i = n_skip;
i < sslot.
nvalues - n_skip;
i++)
872 fcinfo->args[0].value = sslot.
values[
i];
874 fcinfo->args[1].value = sslot.
values[
i];
875 fcinfo->isnull =
false;
880 result = ((double) nmatch) / ((double) (sslot.
nvalues - 2 * n_skip));
916 double default_selectivity)
928 &vardata, &other, &varonleft))
929 return default_selectivity;
936 ((
Const *) other)->constisnull)
945 Datum constval = ((
Const *) other)->constvalue;
973 selec = default_selectivity;
975 else if (hist_size < 100)
982 double hist_weight = hist_size / 100.0;
984 selec = selec * hist_weight +
985 default_selectivity * (1.0 - hist_weight);
991 else if (selec > 0.9999)
1005 selec *= 1.0 - nullfrac - mcvsum;
1011 selec = default_selectivity;
1043 Oid opoid,
FmgrInfo *opproc,
bool isgt,
bool iseq,
1095 bool have_end =
false;
1111 while (lobound < hibound)
1113 int probe = (lobound + hibound) / 2;
1121 if (probe == 0 && sslot.
nvalues > 2)
1143 lobound = probe + 1;
1160 else if (lobound >= sslot.
nvalues)
1171 double eq_selec = 0;
1193 if (
i == 1 || isgt == iseq)
1195 double otherdistinct;
1213 if (otherdistinct > 1)
1214 eq_selec = 1.0 / otherdistinct;
1233 else if (
val <= low)
1235 else if (
val >= high)
1239 binfrac = (
val - low) / (high - low);
1247 if (isnan(binfrac) ||
1248 binfrac < 0.0 || binfrac > 1.0)
1270 histfrac = (double) (
i - 1) + binfrac;
1271 histfrac /= (double) (sslot.
nvalues - 1);
1306 histfrac += eq_selec * (1.0 - binfrac);
1314 histfrac -= eq_selec;
1321 hist_selec = isgt ? (1.0 - histfrac) : histfrac;
1336 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1338 if (hist_selec < cutoff)
1339 hist_selec = cutoff;
1340 else if (hist_selec > 1.0 - cutoff)
1341 hist_selec = 1.0 - cutoff;
1358 fcinfo->args[0].isnull =
false;
1359 fcinfo->args[1].isnull =
false;
1360 fcinfo->args[1].value = constval;
1365 fcinfo->args[0].value = sslot.
values[
i];
1366 fcinfo->isnull =
false;
1371 hist_selec = ((double) nmatch) / ((double) sslot.
nvalues);
1380 double cutoff = 0.01 / (double) (sslot.
nvalues - 1);
1382 if (hist_selec < cutoff)
1383 hist_selec = cutoff;
1384 else if (hist_selec > 1.0 - cutoff)
1385 hist_selec = 1.0 - cutoff;
1419 &vardata, &other, &varonleft))
1435 if (((
Const *) other)->constisnull)
1440 constval = ((
Const *) other)->constvalue;
1441 consttype = ((
Const *) other)->consttype;
1459 selec =
scalarineqsel(root,
operator, isgt, iseq, collation,
1460 &vardata, constval, consttype);
1555 freq_null = stats->stanullfrac;
1571 freq_true = 1.0 - sslot.
numbers[0] - freq_null;
1577 freq_false = 1.0 - freq_true - freq_null;
1579 switch (booltesttype)
1587 selec = 1.0 - freq_null;
1595 selec = 1.0 - freq_true;
1603 selec = 1.0 - freq_false;
1606 elog(
ERROR,
"unrecognized booltesttype: %d",
1607 (
int) booltesttype);
1621 switch (booltesttype)
1629 selec = 1.0 - freq_null;
1634 selec = (1.0 - freq_null) / 2.0;
1640 selec = (freq_null + 1.0) / 2.0;
1643 elog(
ERROR,
"unrecognized booltesttype: %d",
1644 (
int) booltesttype);
1658 switch (booltesttype)
1679 elog(
ERROR,
"unrecognized booltesttype: %d",
1680 (
int) booltesttype);
1712 freq_null = stats->stanullfrac;
1714 switch (nulltesttype)
1729 selec = 1.0 - freq_null;
1732 elog(
ERROR,
"unrecognized nulltesttype: %d",
1733 (
int) nulltesttype);
1738 ((
Var *) vardata.
var)->varattno < 0)
1744 selec = (nulltesttype ==
IS_NULL) ? 0.0 : 1.0;
1751 switch (nulltesttype)
1760 elog(
ERROR,
"unrecognized nulltesttype: %d",
1761 (
int) nulltesttype);
1818 bool is_join_clause,
1824 bool useOr = clause->
useOr;
1825 bool isEquality =
false;
1826 bool isInequality =
false;
1829 Oid nominal_element_type;
1830 Oid nominal_element_collation;
1863 if (
operator == typentry->
eq_opr)
1866 isInequality =
true;
1875 if ((isEquality || isInequality) && !is_join_clause)
1878 nominal_element_type,
1879 isEquality, useOr, varRelid);
1904 if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
1906 else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
1907 isInequality =
true;
1921 if (rightop &&
IsA(rightop,
Const))
1923 Datum arraydatum = ((
Const *) rightop)->constvalue;
1924 bool arrayisnull = ((
Const *) rightop)->constisnull;
1938 &elmlen, &elmbyval, &elmalign);
1941 elmlen, elmbyval, elmalign,
1942 &elem_values, &elem_nulls, &num_elems);
1958 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
1960 for (
i = 0;
i < num_elems;
i++)
1968 nominal_element_collation,
1975 clause->inputcollid,
1983 clause->inputcollid,
1999 s1disjoint +=
s2 - 1.0;
2004 if ((useOr ? isEquality : isInequality) &&
2005 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2017 &elmlen, &elmbyval);
2026 s1 = s1disjoint = (useOr ? 0.0 : 1.0);
2042 clause->inputcollid,
2050 clause->inputcollid,
2066 s1disjoint +=
s2 - 1.0;
2071 if ((useOr ? isEquality : isInequality) &&
2072 s1disjoint >= 0.0 && s1disjoint <= 1.0)
2088 dummyexpr->
typeId = nominal_element_type;
2089 dummyexpr->typeMod = -1;
2090 dummyexpr->collation = clause->inputcollid;
2094 clause->inputcollid,
2102 clause->inputcollid,
2107 s1 = useOr ? 0.0 : 1.0;
2114 for (
i = 0;
i < 10;
i++)
2141 if (arrayexpr &&
IsA(arrayexpr,
Const))
2143 Datum arraydatum = ((
Const *) arrayexpr)->constvalue;
2144 bool arrayisnull = ((
Const *) arrayexpr)->constisnull;
2210 bool is_join_clause;
2226 is_join_clause =
false;
2228 else if (sjinfo == NULL)
2234 is_join_clause =
false;
2293 bool have_mcvs1 =
false;
2294 bool have_mcvs2 =
false;
2296 bool join_is_reversed;
2300 &vardata1, &vardata2, &join_is_reversed);
2307 memset(&sslot1, 0,
sizeof(sslot1));
2308 memset(&sslot2, 0,
sizeof(sslot2));
2327 if (get_mcv_stats &&
2338 if (get_mcv_stats &&
2347 &vardata1, &vardata2,
2349 isdefault1, isdefault2,
2352 have_mcvs1, have_mcvs2);
2359 selec = selec_inner;
2372 if (!join_is_reversed)
2374 &vardata1, &vardata2,
2376 isdefault1, isdefault2,
2379 have_mcvs1, have_mcvs2,
2387 &vardata2, &vardata1,
2389 isdefault2, isdefault1,
2392 have_mcvs2, have_mcvs1,
2406 selec =
Min(selec, inner_rel->
rows * selec_inner);
2410 elog(
ERROR,
"unrecognized join type: %d",
2436 double nd1,
double nd2,
2437 bool isdefault1,
bool isdefault2,
2440 bool have_mcvs1,
bool have_mcvs2)
2444 if (have_mcvs1 && have_mcvs2)
2462 double nullfrac1 = stats1->stanullfrac;
2463 double nullfrac2 = stats2->stanullfrac;
2464 double matchprodfreq,
2486 fcinfo->args[0].isnull =
false;
2487 fcinfo->args[1].isnull =
false;
2498 matchprodfreq = 0.0;
2504 fcinfo->args[0].value = sslot1->
values[
i];
2512 fcinfo->args[1].value = sslot2->
values[
j];
2513 fcinfo->isnull =
false;
2517 hasmatch1[
i] = hasmatch2[
j] =
true;
2526 matchfreq1 = unmatchfreq1 = 0.0;
2532 unmatchfreq1 += sslot1->
numbers[
i];
2536 matchfreq2 = unmatchfreq2 = 0.0;
2542 unmatchfreq2 += sslot2->
numbers[
i];
2553 otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
2554 otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
2566 totalsel1 = matchprodfreq;
2568 totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->
nvalues);
2570 totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
2573 totalsel2 = matchprodfreq;
2575 totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->
nvalues);
2577 totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
2586 selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
2610 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2611 double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
2613 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
2633 double nd1,
double nd2,
2634 bool isdefault1,
bool isdefault2,
2637 bool have_mcvs1,
bool have_mcvs2,
2663 if (nd2 >= vardata2->
rel->
rows)
2669 if (nd2 >= inner_rel->
rows)
2671 nd2 = inner_rel->
rows;
2675 if (have_mcvs1 && have_mcvs2 &&
OidIsValid(opfuncoid))
2689 double nullfrac1 = stats1->stanullfrac;
2704 clamped_nvalues2 =
Min(sslot2->
nvalues, nd2);
2716 fcinfo->args[0].isnull =
false;
2717 fcinfo->args[1].isnull =
false;
2720 hasmatch2 = (
bool *)
palloc0(clamped_nvalues2 *
sizeof(
bool));
2733 fcinfo->args[0].value = sslot1->
values[
i];
2735 for (
j = 0;
j < clamped_nvalues2;
j++)
2741 fcinfo->args[1].value = sslot2->
values[
j];
2742 fcinfo->isnull =
false;
2746 hasmatch1[
i] = hasmatch2[
j] =
true;
2778 if (!isdefault1 && !isdefault2)
2782 if (nd1 <= nd2 || nd2 < 0)
2783 uncertainfrac = 1.0;
2785 uncertainfrac = nd2 / nd1;
2788 uncertainfrac = 0.5;
2789 uncertain = 1.0 - matchfreq1 - nullfrac1;
2791 selec = matchfreq1 + uncertainfrac * uncertain;
2799 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2801 if (!isdefault1 && !isdefault2)
2803 if (nd1 <= nd2 || nd2 < 0)
2804 selec = 1.0 - nullfrac1;
2806 selec = (nd2 / nd1) * (1.0 - nullfrac1);
2809 selec = 0.5 * (1.0 - nullfrac1);
2861 result = 1.0 - nullfrac;
2887 result = 1.0 - result;
2953 Oid opfamily,
int strategy,
bool nulls_first,
2983 *leftstart = *rightstart = 0.0;
2984 *leftend = *rightend = 1.0;
2989 opno = ((
OpExpr *) clause)->opno;
2990 collation = ((
OpExpr *) clause)->inputcollid;
3018 if (op_lefttype == op_righttype)
3022 op_lefttype, op_righttype,
3025 op_lefttype, op_righttype,
3037 op_lefttype, op_righttype,
3040 op_lefttype, op_righttype,
3043 op_lefttype, op_lefttype,
3046 op_righttype, op_righttype,
3051 op_righttype, op_lefttype,
3054 op_righttype, op_lefttype,
3061 if (op_lefttype == op_righttype)
3065 op_lefttype, op_righttype,
3068 op_lefttype, op_righttype,
3073 op_lefttype, op_lefttype,
3082 op_lefttype, op_righttype,
3085 op_lefttype, op_righttype,
3088 op_lefttype, op_lefttype,
3091 op_righttype, op_righttype,
3094 op_lefttype, op_lefttype,
3097 op_righttype, op_righttype,
3100 op_righttype, op_lefttype,
3103 op_righttype, op_lefttype,
3125 &leftmin, &leftmax))
3128 &rightmin, &rightmax))
3135 &leftmax, &leftmin))
3138 &rightmax, &rightmin))
3147 selec =
scalarineqsel(root, leop, isgt,
true, collation, &leftvar,
3148 rightmax, op_righttype);
3153 selec =
scalarineqsel(root, revleop, isgt,
true, collation, &rightvar,
3154 leftmax, op_lefttype);
3164 if (*leftend > *rightend)
3166 else if (*leftend < *rightend)
3169 *leftend = *rightend = 1.0;
3177 selec =
scalarineqsel(root, ltop, isgt,
false, collation, &leftvar,
3178 rightmin, op_righttype);
3183 selec =
scalarineqsel(root, revltop, isgt,
false, collation, &rightvar,
3184 leftmin, op_lefttype);
3186 *rightstart = selec;
3194 if (*leftstart < *rightstart)
3196 else if (*leftstart > *rightstart)
3199 *leftstart = *rightstart = 0.0;
3214 *leftstart += stats->stanullfrac;
3216 *leftend += stats->stanullfrac;
3222 *rightstart += stats->stanullfrac;
3224 *rightend += stats->stanullfrac;
3230 if (*leftstart >= *leftend)
3235 if (*rightstart >= *rightend)
3306 foreach(lc, varinfos)
3318 if (vardata->
rel != varinfo->
rel &&
3337 varinfo->
rel = vardata->
rel;
3340 varinfos =
lappend(varinfos, varinfo);
3420 double srf_multiplier = 1.0;
3426 if (estinfo != NULL)
3442 if (groupExprs ==
NIL || (pgset && *pgset ==
NIL))
3455 foreach(l, groupExprs)
3458 double this_srf_multiplier;
3479 if (srf_multiplier < this_srf_multiplier)
3480 srf_multiplier = this_srf_multiplier;
3483 if (
exprType(groupexpr) == BOOLOID)
3506 groupexpr, &vardata);
3529 if (varshere ==
NIL)
3539 foreach(l2, varshere)
3553 if (varinfos ==
NIL)
3556 numdistinct *= srf_multiplier;
3558 numdistinct = ceil(numdistinct);
3560 if (numdistinct > input_rows)
3561 numdistinct = input_rows;
3562 if (numdistinct < 1.0)
3579 double reldistinct = 1;
3580 double relmaxndistinct = reldistinct;
3581 int relvarcount = 0;
3589 relvarinfos =
lappend(relvarinfos, varinfo1);
3594 if (varinfo2->
rel == varinfo1->
rel)
3597 relvarinfos =
lappend(relvarinfos, varinfo2);
3602 newvarinfos =
lappend(newvarinfos, varinfo2);
3625 reldistinct *= mvndistinct;
3626 if (relmaxndistinct < mvndistinct)
3627 relmaxndistinct = mvndistinct;
3632 foreach(l, relvarinfos)
3637 if (relmaxndistinct < varinfo2->ndistinct)
3645 if (estinfo != NULL && varinfo2->
isdefault)
3667 double clamp = rel->
tuples;
3669 if (relvarcount > 1)
3672 if (clamp < relmaxndistinct)
3674 clamp = relmaxndistinct;
3680 if (reldistinct > clamp)
3681 reldistinct = clamp;
3688 if (reldistinct > 0 && rel->
rows < rel->
tuples)
3726 rel->
tuples / reldistinct));
3733 numdistinct *= reldistinct;
3736 varinfos = newvarinfos;
3737 }
while (varinfos !=
NIL);
3740 numdistinct *= srf_multiplier;
3743 numdistinct = ceil(numdistinct);
3746 if (numdistinct > input_rows)
3747 numdistinct = input_rows;
3748 if (numdistinct < 1.0)
3850 stanullfrac = stats->stanullfrac;
3856 avgfreq = (1.0 - stanullfrac) / ndistinct;
3877 if (ndistinct > nbuckets)
3878 estfract = 1.0 / nbuckets;
3880 estfract = 1.0 / ndistinct;
3885 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
3886 estfract *= *mcv_freq / avgfreq;
3893 if (estfract < 1.0e-6)
3895 else if (estfract > 1.0)
3923 path->pathtarget->width,
3932 return hashentrysize * dNumGroups;
3955 List **varinfos,
double *ndistinct)
3976 int nshared_vars = 0;
3977 int nshared_exprs = 0;
3980 if (info->
kind != STATS_EXT_NDISTINCT)
3992 foreach(lc2, *varinfos)
4020 foreach(lc3, info->
exprs)
4032 if (nshared_vars + nshared_exprs < 2)
4042 if ((nshared_exprs > nmatches_exprs) ||
4043 (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
4046 nmatches_vars = nshared_vars;
4047 nmatches_exprs = nshared_exprs;
4048 matched_info = info;
4056 Assert(nmatches_vars + nmatches_exprs > 1);
4078 if (matched_info->
exprs)
4084 foreach(lc2, *varinfos)
4132 foreach(lc3, matched_info->
exprs)
4199 elog(
ERROR,
"corrupt MVNDistinct entry");
4202 foreach(lc, *varinfos)
4224 newlist =
lappend(newlist, varinfo);
4233 newlist =
lappend(newlist, varinfo);
4249 foreach(lc3, matched_info->
exprs)
4264 newlist =
lappend(newlist, varinfo);
4267 *varinfos = newlist;
4307 double *scaledlobound,
double *scaledhibound)
4309 bool failure =
false;
4343 case REGPROCEDUREOID:
4345 case REGOPERATOROID:
4348 case REGCOLLATIONOID:
4350 case REGDICTIONARYOID:
4352 case REGNAMESPACEOID:
4386 lostr, scaledlobound,
4387 histr, scaledhibound);
4400 if (boundstypid != BYTEAOID)
4403 lobound, scaledlobound,
4404 hibound, scaledhibound);
4412 case TIMESTAMPTZOID:
4441 *scaledvalue = *scaledlobound = *scaledhibound = 0;
4475 case REGPROCEDUREOID:
4477 case REGOPERATOROID:
4480 case REGCOLLATIONOID:
4482 case REGDICTIONARYOID:
4484 case REGNAMESPACEOID:
4515 double *scaledvalue,
4517 double *scaledlobound,
4519 double *scaledhibound)
4525 rangelo = rangehi = (
unsigned char) hibound[0];
4526 for (sptr = lobound; *sptr; sptr++)
4528 if (rangelo > (
unsigned char) *sptr)
4529 rangelo = (
unsigned char) *sptr;
4530 if (rangehi < (
unsigned char) *sptr)
4531 rangehi = (
unsigned char) *sptr;
4533 for (sptr = hibound; *sptr; sptr++)
4535 if (rangelo > (
unsigned char) *sptr)
4536 rangelo = (
unsigned char) *sptr;
4537 if (rangehi < (
unsigned char) *sptr)
4538 rangehi = (
unsigned char) *sptr;
4541 if (rangelo <= 'Z' && rangehi >=
'A')
4549 if (rangelo <= 'z' && rangehi >=
'a')
4557 if (rangelo <= '9' && rangehi >=
'0')
4569 if (rangehi - rangelo < 9)
4580 if (*lobound != *hibound || *lobound != *
value)
4582 lobound++, hibound++,
value++;
4596 int slen = strlen(
value);
4617 base = rangehi - rangelo + 1;
4622 int ch = (
unsigned char) *
value++;
4626 else if (ch > rangehi)
4628 num += ((double) (ch - rangelo)) / denom;
4688 xfrmlen = strxfrm(NULL,
val, 0);
4696 if (xfrmlen == INT_MAX)
4699 xfrmstr = (
char *)
palloc(xfrmlen + 1);
4700 xfrmlen2 = strxfrm(xfrmstr,
val, xfrmlen + 1);
4706 Assert(xfrmlen2 <= xfrmlen);
4727 double *scaledvalue,
4729 double *scaledlobound,
4731 double *scaledhibound)
4743 unsigned char *valstr = (
unsigned char *)
VARDATA_ANY(valuep);
4744 unsigned char *lostr = (
unsigned char *)
VARDATA_ANY(loboundp);
4745 unsigned char *histr = (
unsigned char *)
VARDATA_ANY(hiboundp);
4756 minlen =
Min(
Min(valuelen, loboundlen), hiboundlen);
4757 for (
i = 0;
i < minlen;
i++)
4759 if (*lostr != *histr || *lostr != *valstr)
4761 lostr++, histr++, valstr++;
4762 loboundlen--, hiboundlen--, valuelen--;
4775 int rangelo,
int rangehi)
4792 base = rangehi - rangelo + 1;
4795 while (valuelen-- > 0)
4801 else if (ch > rangehi)
4803 num += ((double) (ch - rangelo)) / denom;
4823 case TIMESTAMPTZOID:
4850 return (
double) (timetz->
time + (timetz->
zone * 1000000.0));
4908 if (vardata->
rel && rdata.
rel == NULL)
4916 if (vardata->
rel == NULL && rdata.
rel)
4945 bool *join_is_reversed)
4951 elog(
ERROR,
"join operator should take two arguments");
4959 if (vardata1->
rel &&
4961 *join_is_reversed =
true;
4962 else if (vardata2->
rel &&
4964 *join_is_reversed =
true;
4966 *join_is_reversed =
false;
5034 if (
IsA(basenode,
Var) &&
5035 (varRelid == 0 || varRelid == ((
Var *) basenode)->varno))
5037 Var *var = (
Var *) basenode;
5040 vardata->
var = basenode;
5042 vardata->
atttype = var->vartype;
5071 if (varRelid == 0 || varRelid == relid)
5074 vardata->
rel = onerel;
5101 vardata->
var = node;
5142 if (indexpr_item == NULL)
5145 for (pos = 0; pos <
index->ncolumns; pos++)
5147 if (
index->indexkeys[pos] == 0)
5151 if (indexpr_item == NULL)
5152 elog(
ERROR,
"too few entries in indexprs list");
5156 if (
equal(node, indexkey))
5162 if (
index->unique &&
5163 index->nkeycolumns == 1 &&
5189 elog(
ERROR,
"no function provided to release variable stats with");
5239 root->append_rel_array != NULL)
5244 appinfo = root->append_rel_array[varno];
5250 appinfo = root->append_rel_array[varno];
5252 if (varno !=
index->rel->relid)
5275 indexpr_item =
lnext(
index->indexprs, indexpr_item);
5303 if (info->
kind != STATS_EXT_EXPRESSIONS)
5311 foreach(expr_item, info->
exprs)
5322 if (
equal(node, expr))
5360 root->append_rel_array != NULL)
5365 appinfo = root->append_rel_array[varno];
5371 appinfo = root->append_rel_array[varno];
5373 if (varno != onerel->
relid)
5422 elog(
ERROR,
"no function provided to release variable stats with");
5481 root->append_rel_array != NULL)
5488 appinfo = root->append_rel_array[varno];
5501 int parent_varattno;
5506 parent_varattno = appinfo->parent_colnos[varattno - 1];
5507 if (parent_varattno == 0)
5511 varattno = parent_varattno;
5515 appinfo = root->append_rel_array[varno];
5602 while (levelsup-- > 0)
5604 cteroot = cteroot->parent_root;
5634 if (subroot == NULL)
5645 subquery = subroot->
parse;
5667 if (ste == NULL || ste->resjunk)
5668 elog(
ERROR,
"subquery %s does not have attribute %d",
5704 if (var &&
IsA(var,
Var) &&
5747 (
errmsg_internal(
"not using statistics because function \"%s\" is not leak-proof",
5767 double stanullfrac = 0.0;
5784 stadistinct = stats->stadistinct;
5785 stanullfrac = stats->stanullfrac;
5787 else if (vardata->
vartype == BOOLOID)
5816 switch (((
Var *) vardata->
var)->varattno)
5845 stadistinct = -1.0 * (1.0 - stanullfrac);
5850 if (stadistinct > 0.0)
5856 if (vardata->
rel == NULL)
5871 if (stadistinct < 0.0)
5898 Oid sortop,
Oid collation,
5903 bool have_data =
false;
5948 STATISTIC_KIND_HISTOGRAM, sortop,
5972 collation, typLen, typByVal,
5973 &tmin, &tmax, &have_data);
5990 bool use_mcvs = have_data;
5994 double sumcommon = 0.0;
6001 if (sumcommon + nullfrac > 0.99999)
6007 collation, typLen, typByVal,
6008 &tmin, &tmax, &have_data);
6025 Oid collation,
int16 typLen,
bool typByVal,
6030 bool have_data = *p_have_data;
6031 bool found_tmin =
false;
6032 bool found_tmax =
false;
6035 if (opproc->
fn_oid != opfuncoid)
6043 tmin = tmax = sslot->
values[
i];
6044 found_tmin = found_tmax =
true;
6045 *p_have_data = have_data =
true;
6068 *min =
datumCopy(tmin, typByVal, typLen);
6070 *max =
datumCopy(tmax, typByVal, typLen);
6088 Oid sortop,
Oid collation,
6091 bool have_data =
false;
6100 rte = root->simple_rte_array[rel->
relid];
6104 if (rte->
relkind == RELKIND_PARTITIONED_TABLE)
6114 if (
index->relam != BTREE_AM_OID)
6128 if (
index->hypothetical)
6135 if (collation !=
index->indexcollations[0])
6142 if (
index->reverse_sort[0])
6148 if (
index->reverse_sort[0])
6174 "get_actual_variable_range workspace",
6219 if (max && have_data)
6275 Datum *endpointDatum)
6277 bool have_data =
false;
6282 int n_visited_heap_pages = 0;
6336 &SnapshotNonVacuumable,
6364 #define VISITED_PAGES_LIMIT 100
6366 if (block != last_heap_block)
6368 last_heap_block = block;
6369 n_visited_heap_pages++;
6391 elog(
ERROR,
"no data returned for index-only scan");
6393 elog(
ERROR,
"unexpected recheck indication from btree");
6402 elog(
ERROR,
"found unexpected null value in index \"%s\"",
6443 elog(
ERROR,
"could not find RelOptInfo for given relids");
6465 foreach(lc, indexclauses)
6474 result =
lappend(result, rinfo);
6492 Cost qual_arg_cost = 0;
6495 foreach(lc, indexquals)
6498 Node *other_operand;
6528 other_operand = NULL;
6532 elog(
ERROR,
"unsupported indexqual type: %d",
6534 other_operand = NULL;
6540 return qual_arg_cost;
6552 Cost indexStartupCost;
6553 Cost indexTotalCost;
6555 double indexCorrelation;
6556 double numIndexPages;
6557 double numIndexTuples;
6558 double spc_random_page_cost;
6559 double num_sa_scans;
6560 double num_outer_scans;
6562 double qual_op_cost;
6563 double qual_arg_cost;
6564 List *selectivityQuals;
6579 foreach(l, indexQuals)
6589 num_sa_scans *= alength;
6605 if (numIndexTuples <= 0.0)
6607 numIndexTuples = indexSelectivity *
index->rel->tuples;
6616 numIndexTuples = rint(numIndexTuples / num_sa_scans);
6624 if (numIndexTuples >
index->tuples)
6625 numIndexTuples =
index->tuples;
6626 if (numIndexTuples < 1.0)
6627 numIndexTuples = 1.0;
6642 numIndexPages = ceil(numIndexTuples *
index->pages /
index->tuples);
6644 numIndexPages = 1.0;
6648 &spc_random_page_cost,
6668 num_outer_scans = loop_count;
6669 num_scans = num_sa_scans * num_outer_scans;
6673 double pages_fetched;
6676 pages_fetched = numIndexPages * num_scans;
6681 (
double)
index->pages,
6689 indexTotalCost = (pages_fetched * spc_random_page_cost)
6698 indexTotalCost = numIndexPages * spc_random_page_cost;
6720 indexStartupCost = qual_arg_cost;
6721 indexTotalCost += qual_arg_cost;
6727 indexCorrelation = 0.0;
6770 foreach(lc,
index->indpred)
6776 predExtraQuals =
list_concat(predExtraQuals, oneQual);
6784 Cost *indexStartupCost,
Cost *indexTotalCost,
6785 Selectivity *indexSelectivity,
double *indexCorrelation,
6793 double numIndexTuples;
6795 List *indexBoundQuals;
6799 bool found_is_null_op;
6800 double num_sa_scans;
6820 indexBoundQuals =
NIL;
6824 found_is_null_op =
false;
6854 clause_op = op->
opno;
6868 clause_op = saop->
opno;
6872 num_sa_scans *= alength;
6880 found_is_null_op =
true;
6886 elog(
ERROR,
"unsupported indexqual type: %d",
6893 index->opfamily[indexcol]);
6894 Assert(op_strategy != 0);
6899 indexBoundQuals =
lappend(indexBoundQuals, rinfo);
6909 if (
index->unique &&
6910 indexcol ==
index->nkeycolumns - 1 &&
6914 numIndexTuples = 1.0;
6917 List *selectivityQuals;
6931 numIndexTuples = btreeSelectivity *
index->rel->tuples;
6938 numIndexTuples = rint(numIndexTuples / num_sa_scans);
6959 if (
index->tuples > 1)
6988 if (
index->indexkeys[0] != 0)
6996 colnum =
index->indexkeys[0];
7007 elog(
ERROR,
"no function provided to release variable stats with");
7021 relid =
index->indexoid;
7033 elog(
ERROR,
"no function provided to release variable stats with");
7051 index->opcintype[0],
7052 index->opcintype[0],
7056 STATISTIC_KIND_CORRELATION, sortop,
7059 double varCorrelation;
7062 varCorrelation = sslot.
numbers[0];
7064 if (
index->reverse_sort[0])
7065 varCorrelation = -varCorrelation;
7067 if (
index->nkeycolumns > 1)
7087 Cost *indexStartupCost,
Cost *indexTotalCost,
7088 Selectivity *indexSelectivity,
double *indexCorrelation,
7129 Cost *indexStartupCost,
Cost *indexTotalCost,
7130 Selectivity *indexSelectivity,
double *indexCorrelation,
7148 if (
index->tree_height < 0)
7150 if (
index->pages > 1)
7151 index->tree_height = (int) (log(
index->pages) / log(100.0));
7153 index->tree_height = 0;
7161 if (
index->tuples > 1)
7184 Cost *indexStartupCost,
Cost *indexTotalCost,
7185 Selectivity *indexSelectivity,
double *indexCorrelation,
7203 if (
index->tree_height < 0)
7205 if (
index->pages > 1)
7206 index->tree_height = (int) (log(
index->pages) / log(100.0));
7208 index->tree_height = 0;
7216 if (
index->tuples > 1)
7269 bool *partial_matches = NULL;
7271 bool *nullFlags = NULL;
7275 Assert(indexcol < index->nkeycolumns);
7284 &strategy_op, &lefttype, &righttype);
7292 index->opcintype[indexcol],
7293 index->opcintype[indexcol],
7299 elog(
ERROR,
"missing support function %d for attribute %d of index \"%s\"",
7308 collation =
index->indexcollations[indexcol];
7310 collation = DEFAULT_COLLATION_OID;
7332 for (
i = 0;
i < nentries;
i++)
7338 if (partial_matches && partial_matches[
i])
7400 if (((
Const *) operand)->constisnull)
7405 ((
Const *) operand)->constvalue,
7426 double numIndexEntries,
7439 int numPossible = 0;
7465 if (((
Const *) rightop)->constisnull)
7471 &elmlen, &elmbyval, &elmalign);
7474 elmlen, elmbyval, elmalign,
7475 &elemValues, &elemNulls, &numElems);
7477 memset(&arraycounts, 0,
sizeof(arraycounts));
7479 for (
i = 0;
i < numElems;
i++)
7488 memset(&elemcounts, 0,
sizeof(elemcounts));
7514 if (numPossible == 0)
7539 Cost *indexStartupCost,
Cost *indexTotalCost,
7540 Selectivity *indexSelectivity,
double *indexCorrelation,
7545 List *selectivityQuals;
7546 double numPages =
index->pages,
7547 numTuples =
index->tuples;
7548 double numEntryPages,
7555 double partialScale;
7556 double entryPagesFetched,
7558 dataPagesFetchedBySel;
7559 double qual_op_cost,
7561 spc_random_page_cost,
7573 if (!
index->hypothetical)
7582 memset(&ginStats, 0,
sizeof(ginStats));
7599 numPendingPages = 0;
7601 if (numPages > 0 && ginStats.
nTotalPages <= numPages &&
7616 numEntryPages =
Min(numEntryPages, numPages - numPendingPages);
7617 numDataPages =
Min(numDataPages,
7618 numPages - numPendingPages - numEntryPages);
7635 numPages =
Max(numPages, 10);
7636 numEntryPages = floor((numPages - numPendingPages) * 0.90);
7637 numDataPages = numPages - numPendingPages - numEntryPages;
7638 numEntries = floor(numEntryPages * 100);
7660 &spc_random_page_cost,
7666 *indexCorrelation = 0.0;
7671 memset(&counts, 0,
sizeof(counts));
7673 matchPossible =
true;
7709 elog(
ERROR,
"unsupported GIN indexqual type: %d",
7718 *indexStartupCost = 0;
7719 *indexTotalCost = 0;
7720 *indexSelectivity = 0;
7730 fullIndexScan =
false;
7731 for (
i = 0;
i <
index->nkeycolumns;
i++)
7735 fullIndexScan =
true;
7740 if (fullIndexScan || indexQuals ==
NIL)
7752 outer_scans = loop_count;
7758 entryPagesFetched = numPendingPages;
7767 entryPagesFetched += ceil(counts.
searchEntries * rint(pow(numEntryPages, 0.15)));
7777 partialScale =
Min(partialScale, 1.0);
7779 entryPagesFetched += ceil(numEntryPages * partialScale);
7786 dataPagesFetched = ceil(numDataPages * partialScale);
7788 *indexStartupCost = 0;
7789 *indexTotalCost = 0;
7834 if (outer_scans > 1 || counts.
arrayScans > 1)
7836 entryPagesFetched *= outer_scans * counts.
arrayScans;
7839 numEntryPages, root);
7840 entryPagesFetched /= outer_scans;
7841 dataPagesFetched *= outer_scans * counts.
arrayScans;
7844 numDataPages, root);
7845 dataPagesFetched /= outer_scans;
7852 *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
7862 dataPagesFetched = ceil(numDataPages * counts.
exactEntries / numEntries);
7875 dataPagesFetchedBySel = ceil(*indexSelectivity *
7876 (numTuples / (BLCKSZ / 3)));
7877 if (dataPagesFetchedBySel > dataPagesFetched)
7878 dataPagesFetched = dataPagesFetchedBySel;
7890 if (outer_scans > 1 || counts.
arrayScans > 1)
7892 dataPagesFetched *= outer_scans * counts.
arrayScans;
7895 numDataPages, root);
7896 dataPagesFetched /= outer_scans;
7900 *indexTotalCost += *indexStartupCost +
7901 dataPagesFetched * spc_random_page_cost;
7911 *indexStartupCost += qual_arg_cost;
7912 *indexTotalCost += qual_arg_cost;
7921 *indexPages = dataPagesFetched;
7929 Cost *indexStartupCost,
Cost *indexTotalCost,
7930 Selectivity *indexSelectivity,
double *indexCorrelation,
7935 double numPages =
index->pages;
7938 Cost spc_seq_page_cost;
7939 Cost spc_random_page_cost;
7940 double qual_arg_cost;
7941 double qualSelectivity;
7944 double minimalRanges;
7945 double estimatedRanges;
7955 &spc_random_page_cost,
7956 &spc_seq_page_cost);
7962 if (!
index->hypothetical)
7972 indexRanges =
Max(ceil((
double) baserel->
pages /
7981 indexRanges =
Max(ceil((
double) baserel->
pages /
7996 *indexCorrelation = 0;
8016 "no function provided to release variable stats with");
8047 elog(
ERROR,
"no function provided to release variable stats with");
8067 double varCorrelation = 0.0;
8070 varCorrelation = fabs(sslot.
numbers[0]);
8072 if (varCorrelation > *indexCorrelation)
8073 *indexCorrelation = varCorrelation;
8090 minimalRanges = ceil(indexRanges * qualSelectivity);
8097 if (*indexCorrelation < 1.0e-10)
8098 estimatedRanges = indexRanges;
8100 estimatedRanges =
Min(minimalRanges / *indexCorrelation, indexRanges);
8103 selec = estimatedRanges / indexRanges;
8107 *indexSelectivity = selec;
8122 *indexStartupCost += qual_arg_cost;
8129 *indexTotalCost = *indexStartupCost +
8130 spc_random_page_cost * (numPages - statsData.
revmapNumPages) * loop_count;
8142 *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)
#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)
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_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)
bool contain_volatile_functions(Node *clause)
double expression_returns_set_rows(PlannerInfo *root, Node *clause)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
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 DateADT DatumGetDateADT(Datum X)
static TimeADT DatumGetTimeADT(Datum X)
static TimeTzADT * DatumGetTimeTzADTP(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)
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)
#define HeapTupleIsValid(tuple)
void index_close(Relation relation, LOCKMODE lockmode)
ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)
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
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
bool list_member_int(const List *list, int datum)
List * list_concat(List *list1, const List *list2)
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)
char * get_rel_name(Oid relid)
char * get_func_name(Oid funcid)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
bool get_func_leakproof(Oid funcid)
Oid get_base_element_type(Oid typid)
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 bool is_opclause(const void *clause)
static Node * get_rightop(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 foreach_delete_current(lst, var_or_cell)
static ListCell * list_head(const List *l)
#define for_each_from(cell, lst, N)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
static int list_nth_int(const List *list, int n)
bool lc_collate_is_c(Oid collation)
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_join_rel(PlannerInfo *root, Relids relids)
RelOptInfo * find_base_rel_noerr(PlannerInfo *root, int relid)
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)
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)
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)
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)
void mergejoinscansel(PlannerInfo *root, Node *clause, Oid opfamily, int strategy, bool nulls_first, Selectivity *leftstart, Selectivity *leftend, Selectivity *rightstart, Selectivity *rightend)
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)
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)
Datum scalarltjoinsel(PG_FUNCTION_ARGS)
static bool gincost_pattern(IndexOptInfo *index, int indexcol, Oid clause_op, Datum query, GinQualCounts *counts)
List * add_predicate_to_index_quals(IndexOptInfo *index, List *indexQuals)
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)
Datum scalarlesel(PG_FUNCTION_ARGS)
static Node * strip_array_coercion(Node *node)
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)
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 List * add_unique_group_var(PlannerInfo *root, List *varinfos, Node *var, VariableStatData *vardata)
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)
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 BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
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)
List * pull_var_clause(Node *node, int flags)
Relids pull_varnos(PlannerInfo *root, Node *node)
#define VARSIZE_ANY_EXHDR(PTR)
#define VM_ALL_VISIBLE(r, b, v)