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;
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++)
2144 if (arrayexpr &&
IsA(arrayexpr,
Const))
2146 Datum arraydatum = ((
Const *) arrayexpr)->constvalue;
2147 bool arrayisnull = ((
Const *) arrayexpr)->constisnull;
2160 else if (arrayexpr &&
root)
2213 bool is_join_clause;
2229 is_join_clause =
false;
2231 else if (sjinfo == NULL)
2237 is_join_clause =
false;
2296 bool have_mcvs1 =
false;
2297 bool have_mcvs2 =
false;
2299 bool join_is_reversed;
2303 &vardata1, &vardata2, &join_is_reversed);
2310 memset(&sslot1, 0,
sizeof(sslot1));
2311 memset(&sslot2, 0,
sizeof(sslot2));
2330 if (get_mcv_stats &&
2341 if (get_mcv_stats &&
2350 &vardata1, &vardata2,
2352 isdefault1, isdefault2,
2355 have_mcvs1, have_mcvs2);
2362 selec = selec_inner;
2375 if (!join_is_reversed)
2377 &vardata1, &vardata2,
2379 isdefault1, isdefault2,
2382 have_mcvs1, have_mcvs2,
2390 &vardata2, &vardata1,
2392 isdefault2, isdefault1,
2395 have_mcvs2, have_mcvs1,
2409 selec =
Min(selec, inner_rel->
rows * selec_inner);
2413 elog(
ERROR,
"unrecognized join type: %d",
2439 double nd1,
double nd2,
2440 bool isdefault1,
bool isdefault2,
2443 bool have_mcvs1,
bool have_mcvs2)
2447 if (have_mcvs1 && have_mcvs2)
2465 double nullfrac1 = stats1->stanullfrac;
2466 double nullfrac2 = stats2->stanullfrac;
2467 double matchprodfreq,
2489 fcinfo->args[0].isnull =
false;
2490 fcinfo->args[1].isnull =
false;
2501 matchprodfreq = 0.0;
2507 fcinfo->args[0].value = sslot1->
values[
i];
2515 fcinfo->args[1].value = sslot2->
values[
j];
2516 fcinfo->isnull =
false;
2520 hasmatch1[
i] = hasmatch2[
j] =
true;
2529 matchfreq1 = unmatchfreq1 = 0.0;
2535 unmatchfreq1 += sslot1->
numbers[
i];
2539 matchfreq2 = unmatchfreq2 = 0.0;
2545 unmatchfreq2 += sslot2->
numbers[
i];
2556 otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
2557 otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
2569 totalsel1 = matchprodfreq;
2571 totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->
nvalues);
2573 totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
2576 totalsel2 = matchprodfreq;
2578 totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->
nvalues);
2580 totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
2589 selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
2613 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2614 double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
2616 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
2636 double nd1,
double nd2,
2637 bool isdefault1,
bool isdefault2,
2640 bool have_mcvs1,
bool have_mcvs2,
2666 if (nd2 >= vardata2->
rel->
rows)
2672 if (nd2 >= inner_rel->
rows)
2674 nd2 = inner_rel->
rows;
2678 if (have_mcvs1 && have_mcvs2 &&
OidIsValid(opfuncoid))
2692 double nullfrac1 = stats1->stanullfrac;
2707 clamped_nvalues2 =
Min(sslot2->
nvalues, nd2);
2719 fcinfo->args[0].isnull =
false;
2720 fcinfo->args[1].isnull =
false;
2723 hasmatch2 = (
bool *)
palloc0(clamped_nvalues2 *
sizeof(
bool));
2736 fcinfo->args[0].value = sslot1->
values[
i];
2738 for (
j = 0;
j < clamped_nvalues2;
j++)
2744 fcinfo->args[1].value = sslot2->
values[
j];
2745 fcinfo->isnull =
false;
2749 hasmatch1[
i] = hasmatch2[
j] =
true;
2781 if (!isdefault1 && !isdefault2)
2785 if (nd1 <= nd2 || nd2 < 0)
2786 uncertainfrac = 1.0;
2788 uncertainfrac = nd2 / nd1;
2791 uncertainfrac = 0.5;
2792 uncertain = 1.0 - matchfreq1 - nullfrac1;
2794 selec = matchfreq1 + uncertainfrac * uncertain;
2802 double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
2804 if (!isdefault1 && !isdefault2)
2806 if (nd1 <= nd2 || nd2 < 0)
2807 selec = 1.0 - nullfrac1;
2809 selec = (nd2 / nd1) * (1.0 - nullfrac1);
2812 selec = 0.5 * (1.0 - nullfrac1);
2864 result = 1.0 - nullfrac;
2890 result = 1.0 - result;
2956 Oid opfamily,
int strategy,
bool nulls_first,
2986 *leftstart = *rightstart = 0.0;
2987 *leftend = *rightend = 1.0;
2992 opno = ((
OpExpr *) clause)->opno;
2993 collation = ((
OpExpr *) clause)->inputcollid;
3021 if (op_lefttype == op_righttype)
3025 op_lefttype, op_righttype,
3028 op_lefttype, op_righttype,
3040 op_lefttype, op_righttype,
3043 op_lefttype, op_righttype,
3046 op_lefttype, op_lefttype,
3049 op_righttype, op_righttype,
3054 op_righttype, op_lefttype,
3057 op_righttype, op_lefttype,
3064 if (op_lefttype == op_righttype)
3068 op_lefttype, op_righttype,
3071 op_lefttype, op_righttype,
3076 op_lefttype, op_lefttype,
3085 op_lefttype, op_righttype,
3088 op_lefttype, op_righttype,
3091 op_lefttype, op_lefttype,
3094 op_righttype, op_righttype,
3097 op_lefttype, op_lefttype,
3100 op_righttype, op_righttype,
3103 op_righttype, op_lefttype,
3106 op_righttype, op_lefttype,
3128 &leftmin, &leftmax))
3131 &rightmin, &rightmax))
3138 &leftmax, &leftmin))
3141 &rightmax, &rightmin))
3151 rightmax, op_righttype);
3157 leftmax, op_lefttype);
3167 if (*leftend > *rightend)
3169 else if (*leftend < *rightend)
3172 *leftend = *rightend = 1.0;
3181 rightmin, op_righttype);
3187 leftmin, op_lefttype);
3189 *rightstart = selec;
3197 if (*leftstart < *rightstart)
3199 else if (*leftstart > *rightstart)
3202 *leftstart = *rightstart = 0.0;
3217 *leftstart += stats->stanullfrac;
3219 *leftend += stats->stanullfrac;
3225 *rightstart += stats->stanullfrac;
3227 *rightend += stats->stanullfrac;
3233 if (*leftstart >= *leftend)
3238 if (*rightstart >= *rightend)
3309 foreach(lc, varinfos)
3322 if (vardata->
rel != varinfo->
rel &&
3341 varinfo->
rel = vardata->
rel;
3344 varinfos =
lappend(varinfos, varinfo);
3424 double srf_multiplier = 1.0;
3430 if (estinfo != NULL)
3446 if (groupExprs ==
NIL || (pgset && *pgset ==
NIL))
3459 foreach(l, groupExprs)
3462 double this_srf_multiplier;
3483 if (srf_multiplier < this_srf_multiplier)
3484 srf_multiplier = this_srf_multiplier;
3487 if (
exprType(groupexpr) == BOOLOID)
3510 groupexpr, &vardata);
3533 if (varshere ==
NIL)
3543 foreach(l2, varshere)
3557 if (varinfos ==
NIL)
3560 numdistinct *= srf_multiplier;
3562 numdistinct = ceil(numdistinct);
3564 if (numdistinct > input_rows)
3565 numdistinct = input_rows;
3566 if (numdistinct < 1.0)
3583 double reldistinct = 1;
3584 double relmaxndistinct = reldistinct;
3585 int relvarcount = 0;
3593 relvarinfos =
lappend(relvarinfos, varinfo1);
3598 if (varinfo2->
rel == varinfo1->
rel)
3601 relvarinfos =
lappend(relvarinfos, varinfo2);
3606 newvarinfos =
lappend(newvarinfos, varinfo2);
3629 reldistinct *= mvndistinct;
3630 if (relmaxndistinct < mvndistinct)
3631 relmaxndistinct = mvndistinct;
3636 foreach(l, relvarinfos)
3641 if (relmaxndistinct < varinfo2->ndistinct)
3649 if (estinfo != NULL && varinfo2->
isdefault)
3671 double clamp = rel->
tuples;
3673 if (relvarcount > 1)
3676 if (clamp < relmaxndistinct)
3678 clamp = relmaxndistinct;
3684 if (reldistinct > clamp)
3685 reldistinct = clamp;
3692 if (reldistinct > 0 && rel->
rows < rel->
tuples)
3730 rel->
tuples / reldistinct));
3737 numdistinct *= reldistinct;
3740 varinfos = newvarinfos;
3741 }
while (varinfos !=
NIL);
3744 numdistinct *= srf_multiplier;
3747 numdistinct = ceil(numdistinct);
3750 if (numdistinct > input_rows)
3751 numdistinct = input_rows;
3752 if (numdistinct < 1.0)
3854 stanullfrac = stats->stanullfrac;
3860 avgfreq = (1.0 - stanullfrac) / ndistinct;
3881 if (ndistinct > nbuckets)
3882 estfract = 1.0 / nbuckets;
3884 estfract = 1.0 / ndistinct;
3889 if (avgfreq > 0.0 && *mcv_freq > avgfreq)
3890 estfract *= *mcv_freq / avgfreq;
3897 if (estfract < 1.0e-6)
3899 else if (estfract > 1.0)
3927 path->pathtarget->width,
3936 return hashentrysize * dNumGroups;
3959 List **varinfos,
double *ndistinct)
3980 int nshared_vars = 0;
3981 int nshared_exprs = 0;
3984 if (info->
kind != STATS_EXT_NDISTINCT)
3996 foreach(lc2, *varinfos)
4024 foreach(lc3, info->
exprs)
4036 if (nshared_vars + nshared_exprs < 2)
4046 if ((nshared_exprs > nmatches_exprs) ||
4047 (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
4050 nmatches_vars = nshared_vars;
4051 nmatches_exprs = nshared_exprs;
4052 matched_info = info;
4060 Assert(nmatches_vars + nmatches_exprs > 1);
4082 if (matched_info->
exprs)
4088 foreach(lc2, *varinfos)
4136 foreach(lc3, matched_info->
exprs)
4203 elog(
ERROR,
"corrupt MVNDistinct entry");
4206 foreach(lc, *varinfos)
4228 newlist =
lappend(newlist, varinfo);
4237 newlist =
lappend(newlist, varinfo);
4253 foreach(lc3, matched_info->
exprs)
4268 newlist =
lappend(newlist, varinfo);
4271 *varinfos = newlist;
4311 double *scaledlobound,
double *scaledhibound)
4313 bool failure =
false;
4347 case REGPROCEDUREOID:
4349 case REGOPERATOROID:
4352 case REGCOLLATIONOID:
4354 case REGDICTIONARYOID:
4356 case REGNAMESPACEOID:
4390 lostr, scaledlobound,
4391 histr, scaledhibound);
4404 if (boundstypid != BYTEAOID)
4407 lobound, scaledlobound,
4408 hibound, scaledhibound);
4416 case TIMESTAMPTZOID:
4445 *scaledvalue = *scaledlobound = *scaledhibound = 0;
4479 case REGPROCEDUREOID:
4481 case REGOPERATOROID:
4484 case REGCOLLATIONOID:
4486 case REGDICTIONARYOID:
4488 case REGNAMESPACEOID:
4519 double *scaledvalue,
4521 double *scaledlobound,
4523 double *scaledhibound)
4529 rangelo = rangehi = (
unsigned char) hibound[0];
4530 for (sptr = lobound; *sptr; sptr++)
4532 if (rangelo > (
unsigned char) *sptr)
4533 rangelo = (
unsigned char) *sptr;
4534 if (rangehi < (
unsigned char) *sptr)
4535 rangehi = (
unsigned char) *sptr;
4537 for (sptr = hibound; *sptr; sptr++)
4539 if (rangelo > (
unsigned char) *sptr)
4540 rangelo = (
unsigned char) *sptr;
4541 if (rangehi < (
unsigned char) *sptr)
4542 rangehi = (
unsigned char) *sptr;
4545 if (rangelo <= 'Z' && rangehi >=
'A')
4553 if (rangelo <= 'z' && rangehi >=
'a')
4561 if (rangelo <= '9' && rangehi >=
'0')
4573 if (rangehi - rangelo < 9)
4584 if (*lobound != *hibound || *lobound != *
value)
4586 lobound++, hibound++,
value++;
4600 int slen = strlen(
value);
4621 base = rangehi - rangelo + 1;
4626 int ch = (
unsigned char) *
value++;
4630 else if (ch > rangehi)
4632 num += ((double) (ch - rangelo)) / denom;
4707 if (xfrmlen == INT_MAX)
4710 xfrmstr = (
char *)
palloc(xfrmlen + 1);
4717 Assert(xfrmlen2 <= xfrmlen);
4738 double *scaledvalue,
4740 double *scaledlobound,
4742 double *scaledhibound)
4754 unsigned char *valstr = (
unsigned char *)
VARDATA_ANY(valuep);
4755 unsigned char *lostr = (
unsigned char *)
VARDATA_ANY(loboundp);
4756 unsigned char *histr = (
unsigned char *)
VARDATA_ANY(hiboundp);
4767 minlen =
Min(
Min(valuelen, loboundlen), hiboundlen);
4768 for (
i = 0;
i < minlen;
i++)
4770 if (*lostr != *histr || *lostr != *valstr)
4772 lostr++, histr++, valstr++;
4773 loboundlen--, hiboundlen--, valuelen--;
4786 int rangelo,
int rangehi)
4803 base = rangehi - rangelo + 1;
4806 while (valuelen-- > 0)
4812 else if (ch > rangehi)
4814 num += ((double) (ch - rangelo)) / denom;
4834 case TIMESTAMPTZOID:
4861 return (
double) (timetz->
time + (timetz->
zone * 1000000.0));
4919 if (vardata->
rel && rdata.
rel == NULL)
4927 if (vardata->
rel == NULL && rdata.
rel)
4956 bool *join_is_reversed)
4962 elog(
ERROR,
"join operator should take two arguments");
4970 if (vardata1->
rel &&
4972 *join_is_reversed =
true;
4973 else if (vardata2->
rel &&
4975 *join_is_reversed =
true;
4977 *join_is_reversed =
false;
5045 if (
IsA(basenode,
Var) &&
5046 (varRelid == 0 || varRelid == ((
Var *) basenode)->varno))
5048 Var *var = (
Var *) basenode;
5051 vardata->
var = basenode;
5053 vardata->
atttype = var->vartype;
5082 if (varRelid == 0 || varRelid == relid)
5085 vardata->
rel = onerel;
5112 vardata->
var = node;
5153 if (indexpr_item == NULL)
5156 for (pos = 0; pos <
index->ncolumns; pos++)
5158 if (
index->indexkeys[pos] == 0)
5162 if (indexpr_item == NULL)
5163 elog(
ERROR,
"too few entries in indexprs list");
5167 if (
equal(node, indexkey))
5173 if (
index->unique &&
5174 index->nkeycolumns == 1 &&
5200 elog(
ERROR,
"no function provided to release variable stats with");
5229 rte->securityQuals ==
NIL &&
5250 root->append_rel_array != NULL)
5255 appinfo =
root->append_rel_array[varno];
5261 appinfo =
root->append_rel_array[varno];
5263 if (varno !=
index->rel->relid)
5270 rte->securityQuals ==
NIL &&
5286 indexpr_item =
lnext(
index->indexprs, indexpr_item);
5314 if (info->
kind != STATS_EXT_EXPRESSIONS)
5322 foreach(expr_item, info->
exprs)
5333 if (
equal(node, expr))
5353 rte->securityQuals ==
NIL &&
5371 root->append_rel_array != NULL)
5376 appinfo =
root->append_rel_array[varno];
5382 appinfo =
root->append_rel_array[varno];
5384 if (varno != onerel->
relid)
5391 rte->securityQuals ==
NIL &&
5433 elog(
ERROR,
"no function provided to release variable stats with");
5475 rte->securityQuals ==
NIL &&
5492 root->append_rel_array != NULL)
5499 appinfo =
root->append_rel_array[varno];
5512 int parent_varattno;
5517 parent_varattno = appinfo->parent_colnos[varattno - 1];
5518 if (parent_varattno == 0)
5522 varattno = parent_varattno;
5526 appinfo =
root->append_rel_array[varno];
5546 rte->securityQuals ==
NIL &&
5613 while (levelsup-- > 0)
5615 cteroot = cteroot->parent_root;
5645 if (subroot == NULL)
5656 subquery = subroot->
parse;
5678 if (ste == NULL || ste->resjunk)
5679 elog(
ERROR,
"subquery %s does not have attribute %d",
5680 rte->eref->aliasname, var->
varattno);
5711 if (rte->security_barrier)
5715 if (var &&
IsA(var,
Var) &&
5758 (
errmsg_internal(
"not using statistics because function \"%s\" is not leak-proof",
5778 double stanullfrac = 0.0;
5795 stadistinct = stats->stadistinct;
5796 stanullfrac = stats->stanullfrac;
5798 else if (vardata->
vartype == BOOLOID)
5827 switch (((
Var *) vardata->
var)->varattno)
5856 stadistinct = -1.0 * (1.0 - stanullfrac);
5861 if (stadistinct > 0.0)
5867 if (vardata->
rel == NULL)
5882 if (stadistinct < 0.0)
5909 Oid sortop,
Oid collation,
5914 bool have_data =
false;
5959 STATISTIC_KIND_HISTOGRAM, sortop,
5983 collation, typLen, typByVal,
5984 &tmin, &tmax, &have_data);
6001 bool use_mcvs = have_data;
6005 double sumcommon = 0.0;
6012 if (sumcommon + nullfrac > 0.99999)
6018 collation, typLen, typByVal,
6019 &tmin, &tmax, &have_data);
6036 Oid collation,
int16 typLen,
bool typByVal,
6041 bool have_data = *p_have_data;
6042 bool found_tmin =
false;
6043 bool found_tmax =
false;
6046 if (opproc->
fn_oid != opfuncoid)
6054 tmin = tmax = sslot->
values[
i];
6055 found_tmin = found_tmax =
true;
6056 *p_have_data = have_data =
true;
6079 *min =
datumCopy(tmin, typByVal, typLen);
6081 *max =
datumCopy(tmax, typByVal, typLen);
6099 Oid sortop,
Oid collation,
6102 bool have_data =
false;
6111 rte =
root->simple_rte_array[rel->
relid];
6115 if (rte->relkind == RELKIND_PARTITIONED_TABLE)
6125 if (
index->relam != BTREE_AM_OID)
6139 if (
index->hypothetical)
6146 if (collation !=
index->indexcollations[0])
6153 if (
index->reverse_sort[0])
6159 if (
index->reverse_sort[0])
6185 "get_actual_variable_range workspace",
6230 if (max && have_data)
6286 Datum *endpointDatum)
6288 bool have_data =
false;
6293 int n_visited_heap_pages = 0;
6347 &SnapshotNonVacuumable,
6375#define VISITED_PAGES_LIMIT 100
6377 if (block != last_heap_block)
6379 last_heap_block = block;
6380 n_visited_heap_pages++;
6402 elog(
ERROR,
"no data returned for index-only scan");
6404 elog(
ERROR,
"unexpected recheck indication from btree");
6413 elog(
ERROR,
"found unexpected null value in index \"%s\"",
6454 elog(
ERROR,
"could not find RelOptInfo for given relids");
6476 foreach(lc, indexclauses)
6485 result =
lappend(result, rinfo);
6503 Cost qual_arg_cost = 0;
6506 foreach(lc, indexquals)
6509 Node *other_operand;
6539 other_operand = NULL;
6543 elog(
ERROR,
"unsupported indexqual type: %d",
6545 other_operand = NULL;
6551 return qual_arg_cost;
6563 Cost indexStartupCost;
6564 Cost indexTotalCost;
6566 double indexCorrelation;
6567 double numIndexPages;
6568 double numIndexTuples;
6569 double spc_random_page_cost;
6570 double num_sa_scans;
6571 double num_outer_scans;
6573 double qual_op_cost;
6574 double qual_arg_cost;
6575 List *selectivityQuals;
6591 if (num_sa_scans < 1)
6594 foreach(l, indexQuals)
6604 num_sa_scans *= alength;
6621 if (numIndexTuples <= 0.0)
6623 numIndexTuples = indexSelectivity *
index->rel->tuples;
6632 numIndexTuples = rint(numIndexTuples / num_sa_scans);
6640 if (numIndexTuples >
index->tuples)
6641 numIndexTuples =
index->tuples;
6642 if (numIndexTuples < 1.0)
6643 numIndexTuples = 1.0;
6658 numIndexPages = ceil(numIndexTuples *
index->pages /
index->tuples);
6660 numIndexPages = 1.0;
6664 &spc_random_page_cost,
6684 num_outer_scans = loop_count;
6685 num_scans = num_sa_scans * num_outer_scans;
6689 double pages_fetched;
6692 pages_fetched = numIndexPages * num_scans;
6697 (
double)
index->pages,
6705 indexTotalCost = (pages_fetched * spc_random_page_cost)
6714 indexTotalCost = numIndexPages * spc_random_page_cost;
6736 indexStartupCost = qual_arg_cost;
6737 indexTotalCost += qual_arg_cost;
6743 indexCorrelation = 0.0;
6786 foreach(lc,
index->indpred)
6792 predExtraQuals =
list_concat(predExtraQuals, oneQual);
6800 Cost *indexStartupCost,
Cost *indexTotalCost,
6801 Selectivity *indexSelectivity,
double *indexCorrelation,
6809 double numIndexTuples;
6811 List *indexBoundQuals;
6815 bool found_is_null_op;
6816 double num_sa_scans;
6836 indexBoundQuals =
NIL;
6840 found_is_null_op =
false;
6870 clause_op = op->
opno;
6884 clause_op = saop->
opno;
6888 num_sa_scans *= alength;
6896 found_is_null_op =
true;
6902 elog(
ERROR,
"unsupported indexqual type: %d",
6909 index->opfamily[indexcol]);
6910 Assert(op_strategy != 0);
6915 indexBoundQuals =
lappend(indexBoundQuals, rinfo);
6925 if (
index->unique &&
6926 indexcol ==
index->nkeycolumns - 1 &&
6930 numIndexTuples = 1.0;
6933 List *selectivityQuals;
6947 numIndexTuples = btreeSelectivity *
index->rel->tuples;
6969 num_sa_scans =
Min(num_sa_scans, ceil(
index->pages * 0.3333333));
6970 num_sa_scans =
Max(num_sa_scans, 1);
6992 numIndexTuples = rint(numIndexTuples / num_sa_scans);
7014 if (
index->tuples > 1)
7044 if (
index->indexkeys[0] != 0)
7052 colnum =
index->indexkeys[0];
7063 elog(
ERROR,
"no function provided to release variable stats with");
7077 relid =
index->indexoid;
7089 elog(
ERROR,
"no function provided to release variable stats with");
7107 index->opcintype[0],
7108 index->opcintype[0],
7112 STATISTIC_KIND_CORRELATION, sortop,
7115 double varCorrelation;
7118 varCorrelation = sslot.
numbers[0];
7120 if (
index->reverse_sort[0])
7121 varCorrelation = -varCorrelation;
7123 if (
index->nkeycolumns > 1)
7143 Cost *indexStartupCost,
Cost *indexTotalCost,
7144 Selectivity *indexSelectivity,
double *indexCorrelation,
7185 Cost *indexStartupCost,
Cost *indexTotalCost,
7186 Selectivity *indexSelectivity,
double *indexCorrelation,
7204 if (
index->tree_height < 0)
7206 if (
index->pages > 1)
7207 index->tree_height = (int) (log(
index->pages) / log(100.0));
7209 index->tree_height = 0;
7217 if (
index->tuples > 1)
7240 Cost *indexStartupCost,
Cost *indexTotalCost,
7241 Selectivity *indexSelectivity,
double *indexCorrelation,
7259 if (
index->tree_height < 0)
7261 if (
index->pages > 1)
7262 index->tree_height = (int) (log(
index->pages) / log(100.0));
7264 index->tree_height = 0;
7272 if (
index->tuples > 1)
7325 bool *partial_matches = NULL;
7327 bool *nullFlags = NULL;
7331 Assert(indexcol < index->nkeycolumns);
7340 &strategy_op, &lefttype, &righttype);
7348 index->opcintype[indexcol],
7349 index->opcintype[indexcol],
7355 elog(
ERROR,
"missing support function %d for attribute %d of index \"%s\"",
7364 collation =
index->indexcollations[indexcol];
7366 collation = DEFAULT_COLLATION_OID;
7388 for (
i = 0;
i < nentries;
i++)
7394 if (partial_matches && partial_matches[
i])
7456 if (((
Const *) operand)->constisnull)
7461 ((
Const *) operand)->constvalue,
7482 double numIndexEntries,
7495 int numPossible = 0;
7521 if (((
Const *) rightop)->constisnull)
7527 &elmlen, &elmbyval, &elmalign);
7530 elmlen, elmbyval, elmalign,
7531 &elemValues, &elemNulls, &numElems);
7533 memset(&arraycounts, 0,
sizeof(arraycounts));
7535 for (
i = 0;
i < numElems;
i++)
7544 memset(&elemcounts, 0,
sizeof(elemcounts));
7570 if (numPossible == 0)
7595 Cost *indexStartupCost,
Cost *indexTotalCost,
7596 Selectivity *indexSelectivity,
double *indexCorrelation,
7601 List *selectivityQuals;
7602 double numPages =
index->pages,
7603 numTuples =
index->tuples;
7604 double numEntryPages,
7611 double partialScale;
7612 double entryPagesFetched,
7614 dataPagesFetchedBySel;
7615 double qual_op_cost,
7617 spc_random_page_cost,
7629 if (!
index->hypothetical)
7638 memset(&ginStats, 0,
sizeof(ginStats));
7655 numPendingPages = 0;
7657 if (numPages > 0 && ginStats.
nTotalPages <= numPages &&
7672 numEntryPages =
Min(numEntryPages, numPages - numPendingPages);
7673 numDataPages =
Min(numDataPages,
7674 numPages - numPendingPages - numEntryPages);
7691 numPages =
Max(numPages, 10);
7692 numEntryPages = floor((numPages - numPendingPages) * 0.90);
7693 numDataPages = numPages - numPendingPages - numEntryPages;
7694 numEntries = floor(numEntryPages * 100);
7716 &spc_random_page_cost,
7722 *indexCorrelation = 0.0;
7727 memset(&counts, 0,
sizeof(counts));
7729 matchPossible =
true;
7765 elog(
ERROR,
"unsupported GIN indexqual type: %d",
7774 *indexStartupCost = 0;
7775 *indexTotalCost = 0;
7776 *indexSelectivity = 0;
7786 fullIndexScan =
false;
7787 for (
i = 0;
i <
index->nkeycolumns;
i++)
7791 fullIndexScan =
true;
7796 if (fullIndexScan || indexQuals ==
NIL)
7808 outer_scans = loop_count;
7814 entryPagesFetched = numPendingPages;
7823 entryPagesFetched += ceil(counts.
searchEntries * rint(pow(numEntryPages, 0.15)));
7833 partialScale =
Min(partialScale, 1.0);
7835 entryPagesFetched += ceil(numEntryPages * partialScale);
7842 dataPagesFetched = ceil(numDataPages * partialScale);
7844 *indexStartupCost = 0;
7845 *indexTotalCost = 0;
7890 if (outer_scans > 1 || counts.
arrayScans > 1)
7892 entryPagesFetched *= outer_scans * counts.
arrayScans;
7895 numEntryPages,
root);
7896 entryPagesFetched /= outer_scans;
7897 dataPagesFetched *= outer_scans * counts.
arrayScans;
7900 numDataPages,
root);
7901 dataPagesFetched /= outer_scans;
7908 *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
7918 dataPagesFetched = ceil(numDataPages * counts.
exactEntries / numEntries);
7931 dataPagesFetchedBySel = ceil(*indexSelectivity *
7932 (numTuples / (BLCKSZ / 3)));
7933 if (dataPagesFetchedBySel > dataPagesFetched)
7934 dataPagesFetched = dataPagesFetchedBySel;
7946 if (outer_scans > 1 || counts.
arrayScans > 1)
7948 dataPagesFetched *= outer_scans * counts.
arrayScans;
7951 numDataPages,
root);
7952 dataPagesFetched /= outer_scans;
7956 *indexTotalCost += *indexStartupCost +
7957 dataPagesFetched * spc_random_page_cost;
7967 *indexStartupCost += qual_arg_cost;
7968 *indexTotalCost += qual_arg_cost;
7977 *indexPages = dataPagesFetched;
7985 Cost *indexStartupCost,
Cost *indexTotalCost,
7986 Selectivity *indexSelectivity,
double *indexCorrelation,
7991 double numPages =
index->pages;
7994 Cost spc_seq_page_cost;
7995 Cost spc_random_page_cost;
7996 double qual_arg_cost;
7997 double qualSelectivity;
8000 double minimalRanges;
8001 double estimatedRanges;
8011 &spc_random_page_cost,
8012 &spc_seq_page_cost);
8018 if (!
index->hypothetical)
8028 indexRanges =
Max(ceil((
double) baserel->
pages /
8037 indexRanges =
Max(ceil((
double) baserel->
pages /
8052 *indexCorrelation = 0;
8072 "no function provided to release variable stats with");
8103 elog(
ERROR,
"no function provided to release variable stats with");
8123 double varCorrelation = 0.0;
8126 varCorrelation = fabs(sslot.
numbers[0]);
8128 if (varCorrelation > *indexCorrelation)
8129 *indexCorrelation = varCorrelation;
8146 minimalRanges = ceil(indexRanges * qualSelectivity);
8153 if (*indexCorrelation < 1.0e-10)
8154 estimatedRanges = indexRanges;
8156 estimatedRanges =
Min(minimalRanges / *indexCorrelation, indexRanges);
8159 selec = estimatedRanges / indexRanges;
8163 *indexSelectivity = selec;
8178 *indexStartupCost += qual_arg_cost;
8185 *indexTotalCost = *indexStartupCost +
8186 spc_random_page_cost * (numPages - statsData.
revmapNumPages) * loop_count;
8198 *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 Assert(condition)
#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)
#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
List * lappend(List *list, void *datum)
List * list_concat(List *list1, const List *list2)
bool list_member_int(const List *list, int datum)
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)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Oid get_negator(Oid opno)
Oid get_commutator(Oid opno)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
MVNDistinct * statext_ndistinct_load(Oid mvoid, bool inh)
double convert_network_to_scalar(Datum value, Oid typid, bool *failure)
Size hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
static Node * get_rightop(const void *clause)
static bool is_opclause(const void *clause)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
#define PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_PLACEHOLDERS
#define PVC_RECURSE_WINDOWFUNCS
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)
#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)
MemoryContextSwitchTo(old_ctx)
#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)
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)
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)
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)
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)
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)
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)
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)
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)
Relids pull_varnos(PlannerInfo *root, Node *node)
List * pull_var_clause(Node *node, int flags)
#define VARSIZE_ANY_EXHDR(PTR)
#define VM_ALL_VISIBLE(r, b, v)