LCOV - code coverage report
Current view: top level - src/backend/utils/adt - selfuncs.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 88.2 % 2577 2272
Test Date: 2026-03-05 18:14:42 Functions: 96.3 % 81 78
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * selfuncs.c
       4              :  *    Selectivity functions and index cost estimation functions for
       5              :  *    standard operators and index access methods.
       6              :  *
       7              :  *    Selectivity routines are registered in the pg_operator catalog
       8              :  *    in the "oprrest" and "oprjoin" attributes.
       9              :  *
      10              :  *    Index cost functions are located via the index AM's API struct,
      11              :  *    which is obtained from the handler function registered in pg_am.
      12              :  *
      13              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      14              :  * Portions Copyright (c) 1994, Regents of the University of California
      15              :  *
      16              :  *
      17              :  * IDENTIFICATION
      18              :  *    src/backend/utils/adt/selfuncs.c
      19              :  *
      20              :  *-------------------------------------------------------------------------
      21              :  */
      22              : 
      23              : /*----------
      24              :  * Operator selectivity estimation functions are called to estimate the
      25              :  * selectivity of WHERE clauses whose top-level operator is their operator.
      26              :  * We divide the problem into two cases:
      27              :  *      Restriction clause estimation: the clause involves vars of just
      28              :  *          one relation.
      29              :  *      Join clause estimation: the clause involves vars of multiple rels.
      30              :  * Join selectivity estimation is far more difficult and usually less accurate
      31              :  * than restriction estimation.
      32              :  *
      33              :  * When dealing with the inner scan of a nestloop join, we consider the
      34              :  * join's joinclauses as restriction clauses for the inner relation, and
      35              :  * treat vars of the outer relation as parameters (a/k/a constants of unknown
      36              :  * values).  So, restriction estimators need to be able to accept an argument
      37              :  * telling which relation is to be treated as the variable.
      38              :  *
      39              :  * The call convention for a restriction estimator (oprrest function) is
      40              :  *
      41              :  *      Selectivity oprrest (PlannerInfo *root,
      42              :  *                           Oid operator,
      43              :  *                           List *args,
      44              :  *                           int varRelid);
      45              :  *
      46              :  * root: general information about the query (rtable and RelOptInfo lists
      47              :  * are particularly important for the estimator).
      48              :  * operator: OID of the specific operator in question.
      49              :  * args: argument list from the operator clause.
      50              :  * varRelid: if not zero, the relid (rtable index) of the relation to
      51              :  * be treated as the variable relation.  May be zero if the args list
      52              :  * is known to contain vars of only one relation.
      53              :  *
      54              :  * This is represented at the SQL level (in pg_proc) as
      55              :  *
      56              :  *      float8 oprrest (internal, oid, internal, int4);
      57              :  *
      58              :  * The result is a selectivity, that is, a fraction (0 to 1) of the rows
      59              :  * of the relation that are expected to produce a TRUE result for the
      60              :  * given operator.
      61              :  *
      62              :  * The call convention for a join estimator (oprjoin function) is similar
      63              :  * except that varRelid is not needed, and instead join information is
      64              :  * supplied:
      65              :  *
      66              :  *      Selectivity oprjoin (PlannerInfo *root,
      67              :  *                           Oid operator,
      68              :  *                           List *args,
      69              :  *                           JoinType jointype,
      70              :  *                           SpecialJoinInfo *sjinfo);
      71              :  *
      72              :  *      float8 oprjoin (internal, oid, internal, int2, internal);
      73              :  *
      74              :  * (Before Postgres 8.4, join estimators had only the first four of these
      75              :  * parameters.  That signature is still allowed, but deprecated.)  The
      76              :  * relationship between jointype and sjinfo is explained in the comments for
      77              :  * clause_selectivity() --- the short version is that jointype is usually
      78              :  * best ignored in favor of examining sjinfo.
      79              :  *
      80              :  * Join selectivity for regular inner and outer joins is defined as the
      81              :  * fraction (0 to 1) of the cross product of the relations that is expected
      82              :  * to produce a TRUE result for the given operator.  For both semi and anti
      83              :  * joins, however, the selectivity is defined as the fraction of the left-hand
      84              :  * side relation's rows that are expected to have a match (ie, at least one
      85              :  * row with a TRUE result) in the right-hand side.
      86              :  *
      87              :  * For both oprrest and oprjoin functions, the operator's input collation OID
      88              :  * (if any) is passed using the standard fmgr mechanism, so that the estimator
      89              :  * function can fetch it with PG_GET_COLLATION().  Note, however, that all
      90              :  * statistics in pg_statistic are currently built using the relevant column's
      91              :  * collation.
      92              :  *----------
      93              :  */
      94              : 
      95              : #include "postgres.h"
      96              : 
      97              : #include <ctype.h>
      98              : #include <math.h>
      99              : 
     100              : #include "access/brin.h"
     101              : #include "access/brin_page.h"
     102              : #include "access/gin.h"
     103              : #include "access/table.h"
     104              : #include "access/tableam.h"
     105              : #include "access/visibilitymap.h"
     106              : #include "catalog/pg_collation.h"
     107              : #include "catalog/pg_operator.h"
     108              : #include "catalog/pg_statistic.h"
     109              : #include "catalog/pg_statistic_ext.h"
     110              : #include "executor/nodeAgg.h"
     111              : #include "miscadmin.h"
     112              : #include "nodes/makefuncs.h"
     113              : #include "nodes/nodeFuncs.h"
     114              : #include "optimizer/clauses.h"
     115              : #include "optimizer/cost.h"
     116              : #include "optimizer/optimizer.h"
     117              : #include "optimizer/pathnode.h"
     118              : #include "optimizer/paths.h"
     119              : #include "optimizer/plancat.h"
     120              : #include "parser/parse_clause.h"
     121              : #include "parser/parse_relation.h"
     122              : #include "parser/parsetree.h"
     123              : #include "rewrite/rewriteManip.h"
     124              : #include "statistics/statistics.h"
     125              : #include "storage/bufmgr.h"
     126              : #include "utils/acl.h"
     127              : #include "utils/array.h"
     128              : #include "utils/builtins.h"
     129              : #include "utils/date.h"
     130              : #include "utils/datum.h"
     131              : #include "utils/fmgroids.h"
     132              : #include "utils/index_selfuncs.h"
     133              : #include "utils/lsyscache.h"
     134              : #include "utils/memutils.h"
     135              : #include "utils/pg_locale.h"
     136              : #include "utils/rel.h"
     137              : #include "utils/selfuncs.h"
     138              : #include "utils/snapmgr.h"
     139              : #include "utils/spccache.h"
     140              : #include "utils/syscache.h"
     141              : #include "utils/timestamp.h"
     142              : #include "utils/typcache.h"
     143              : 
     144              : #define DEFAULT_PAGE_CPU_MULTIPLIER 50.0
     145              : 
     146              : /*
     147              :  * In production builds, switch to hash-based MCV matching when the lists are
     148              :  * large enough to amortize hash setup cost.  (This threshold is compared to
     149              :  * the sum of the lengths of the two MCV lists.  This is simplistic but seems
     150              :  * to work well enough.)  In debug builds, we use a smaller threshold so that
     151              :  * the regression tests cover both paths well.
     152              :  */
     153              : #ifndef USE_ASSERT_CHECKING
     154              : #define EQJOINSEL_MCV_HASH_THRESHOLD 200
     155              : #else
     156              : #define EQJOINSEL_MCV_HASH_THRESHOLD 20
     157              : #endif
     158              : 
     159              : /* Entries in the simplehash hash table used by eqjoinsel_find_matches */
     160              : typedef struct MCVHashEntry
     161              : {
     162              :     Datum       value;          /* the value represented by this entry */
     163              :     int         index;          /* its index in the relevant AttStatsSlot */
     164              :     uint32      hash;           /* hash code for the Datum */
     165              :     char        status;         /* status code used by simplehash.h */
     166              : } MCVHashEntry;
     167              : 
     168              : /* private_data for the simplehash hash table */
     169              : typedef struct MCVHashContext
     170              : {
     171              :     FunctionCallInfo equal_fcinfo;  /* the equality join operator */
     172              :     FunctionCallInfo hash_fcinfo;   /* the hash function to use */
     173              :     bool        op_is_reversed; /* equality compares hash type to probe type */
     174              :     bool        insert_mode;    /* doing inserts or lookups? */
     175              :     bool        hash_typbyval;  /* typbyval of hashed data type */
     176              :     int16       hash_typlen;    /* typlen of hashed data type */
     177              : } MCVHashContext;
     178              : 
     179              : /* forward reference */
     180              : typedef struct MCVHashTable_hash MCVHashTable_hash;
     181              : 
     182              : /* Hooks for plugins to get control when we ask for stats */
     183              : get_relation_stats_hook_type get_relation_stats_hook = NULL;
     184              : get_index_stats_hook_type get_index_stats_hook = NULL;
     185              : 
     186              : static double eqsel_internal(PG_FUNCTION_ARGS, bool negate);
     187              : static double eqjoinsel_inner(FmgrInfo *eqproc, Oid collation,
     188              :                               Oid hashLeft, Oid hashRight,
     189              :                               VariableStatData *vardata1, VariableStatData *vardata2,
     190              :                               double nd1, double nd2,
     191              :                               bool isdefault1, bool isdefault2,
     192              :                               AttStatsSlot *sslot1, AttStatsSlot *sslot2,
     193              :                               Form_pg_statistic stats1, Form_pg_statistic stats2,
     194              :                               bool have_mcvs1, bool have_mcvs2,
     195              :                               bool *hasmatch1, bool *hasmatch2,
     196              :                               int *p_nmatches);
     197              : static double eqjoinsel_semi(FmgrInfo *eqproc, Oid collation,
     198              :                              Oid hashLeft, Oid hashRight,
     199              :                              bool op_is_reversed,
     200              :                              VariableStatData *vardata1, VariableStatData *vardata2,
     201              :                              double nd1, double nd2,
     202              :                              bool isdefault1, bool isdefault2,
     203              :                              AttStatsSlot *sslot1, AttStatsSlot *sslot2,
     204              :                              Form_pg_statistic stats1, Form_pg_statistic stats2,
     205              :                              bool have_mcvs1, bool have_mcvs2,
     206              :                              bool *hasmatch1, bool *hasmatch2,
     207              :                              int *p_nmatches,
     208              :                              RelOptInfo *inner_rel);
     209              : static void eqjoinsel_find_matches(FmgrInfo *eqproc, Oid collation,
     210              :                                    Oid hashLeft, Oid hashRight,
     211              :                                    bool op_is_reversed,
     212              :                                    AttStatsSlot *sslot1, AttStatsSlot *sslot2,
     213              :                                    int nvalues1, int nvalues2,
     214              :                                    bool *hasmatch1, bool *hasmatch2,
     215              :                                    int *p_nmatches, double *p_matchprodfreq);
     216              : static uint32 hash_mcv(MCVHashTable_hash *tab, Datum key);
     217              : static bool mcvs_equal(MCVHashTable_hash *tab, Datum key0, Datum key1);
     218              : static bool estimate_multivariate_ndistinct(PlannerInfo *root,
     219              :                                             RelOptInfo *rel, List **varinfos, double *ndistinct);
     220              : static bool convert_to_scalar(Datum value, Oid valuetypid, Oid collid,
     221              :                               double *scaledvalue,
     222              :                               Datum lobound, Datum hibound, Oid boundstypid,
     223              :                               double *scaledlobound, double *scaledhibound);
     224              : static double convert_numeric_to_scalar(Datum value, Oid typid, bool *failure);
     225              : static void convert_string_to_scalar(char *value,
     226              :                                      double *scaledvalue,
     227              :                                      char *lobound,
     228              :                                      double *scaledlobound,
     229              :                                      char *hibound,
     230              :                                      double *scaledhibound);
     231              : static void convert_bytea_to_scalar(Datum value,
     232              :                                     double *scaledvalue,
     233              :                                     Datum lobound,
     234              :                                     double *scaledlobound,
     235              :                                     Datum hibound,
     236              :                                     double *scaledhibound);
     237              : static double convert_one_string_to_scalar(char *value,
     238              :                                            int rangelo, int rangehi);
     239              : static double convert_one_bytea_to_scalar(unsigned char *value, int valuelen,
     240              :                                           int rangelo, int rangehi);
     241              : static char *convert_string_datum(Datum value, Oid typid, Oid collid,
     242              :                                   bool *failure);
     243              : static double convert_timevalue_to_scalar(Datum value, Oid typid,
     244              :                                           bool *failure);
     245              : static Node *strip_all_phvs_deep(PlannerInfo *root, Node *node);
     246              : static bool contain_placeholder_walker(Node *node, void *context);
     247              : static Node *strip_all_phvs_mutator(Node *node, void *context);
     248              : static void examine_simple_variable(PlannerInfo *root, Var *var,
     249              :                                     VariableStatData *vardata);
     250              : static void examine_indexcol_variable(PlannerInfo *root, IndexOptInfo *index,
     251              :                                       int indexcol, VariableStatData *vardata);
     252              : static bool get_variable_range(PlannerInfo *root, VariableStatData *vardata,
     253              :                                Oid sortop, Oid collation,
     254              :                                Datum *min, Datum *max);
     255              : static void get_stats_slot_range(AttStatsSlot *sslot,
     256              :                                  Oid opfuncoid, FmgrInfo *opproc,
     257              :                                  Oid collation, int16 typLen, bool typByVal,
     258              :                                  Datum *min, Datum *max, bool *p_have_data);
     259              : static bool get_actual_variable_range(PlannerInfo *root,
     260              :                                       VariableStatData *vardata,
     261              :                                       Oid sortop, Oid collation,
     262              :                                       Datum *min, Datum *max);
     263              : static bool get_actual_variable_endpoint(Relation heapRel,
     264              :                                          Relation indexRel,
     265              :                                          ScanDirection indexscandir,
     266              :                                          ScanKey scankeys,
     267              :                                          int16 typLen,
     268              :                                          bool typByVal,
     269              :                                          TupleTableSlot *tableslot,
     270              :                                          MemoryContext outercontext,
     271              :                                          Datum *endpointDatum);
     272              : static RelOptInfo *find_join_input_rel(PlannerInfo *root, Relids relids);
     273              : static double btcost_correlation(IndexOptInfo *index,
     274              :                                  VariableStatData *vardata);
     275              : 
     276              : /* Define support routines for MCV hash tables */
     277              : #define SH_PREFIX               MCVHashTable
     278              : #define SH_ELEMENT_TYPE         MCVHashEntry
     279              : #define SH_KEY_TYPE             Datum
     280              : #define SH_KEY                  value
     281              : #define SH_HASH_KEY(tab,key)    hash_mcv(tab, key)
     282              : #define SH_EQUAL(tab,key0,key1) mcvs_equal(tab, key0, key1)
     283              : #define SH_SCOPE                static inline
     284              : #define SH_STORE_HASH
     285              : #define SH_GET_HASH(tab,ent)    (ent)->hash
     286              : #define SH_DEFINE
     287              : #define SH_DECLARE
     288              : #include "lib/simplehash.h"
     289              : 
     290              : 
     291              : /*
     292              :  *      eqsel           - Selectivity of "=" for any data types.
     293              :  *
     294              :  * Note: this routine is also used to estimate selectivity for some
     295              :  * operators that are not "=" but have comparable selectivity behavior,
     296              :  * such as "~=" (geometric approximate-match).  Even for "=", we must
     297              :  * keep in mind that the left and right datatypes may differ.
     298              :  */
     299              : Datum
     300       411510 : eqsel(PG_FUNCTION_ARGS)
     301              : {
     302       411510 :     PG_RETURN_FLOAT8((float8) eqsel_internal(fcinfo, false));
     303              : }
     304              : 
     305              : /*
     306              :  * Common code for eqsel() and neqsel()
     307              :  */
     308              : static double
     309       436995 : eqsel_internal(PG_FUNCTION_ARGS, bool negate)
     310              : {
     311       436995 :     PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
     312       436995 :     Oid         operator = PG_GETARG_OID(1);
     313       436995 :     List       *args = (List *) PG_GETARG_POINTER(2);
     314       436995 :     int         varRelid = PG_GETARG_INT32(3);
     315       436995 :     Oid         collation = PG_GET_COLLATION();
     316              :     VariableStatData vardata;
     317              :     Node       *other;
     318              :     bool        varonleft;
     319              :     double      selec;
     320              : 
     321              :     /*
     322              :      * When asked about <>, we do the estimation using the corresponding =
     323              :      * operator, then convert to <> via "1.0 - eq_selectivity - nullfrac".
     324              :      */
     325       436995 :     if (negate)
     326              :     {
     327        25485 :         operator = get_negator(operator);
     328        25485 :         if (!OidIsValid(operator))
     329              :         {
     330              :             /* Use default selectivity (should we raise an error instead?) */
     331            0 :             return 1.0 - DEFAULT_EQ_SEL;
     332              :         }
     333              :     }
     334              : 
     335              :     /*
     336              :      * If expression is not variable = something or something = variable, then
     337              :      * punt and return a default estimate.
     338              :      */
     339       436995 :     if (!get_restriction_variable(root, args, varRelid,
     340              :                                   &vardata, &other, &varonleft))
     341         2842 :         return negate ? (1.0 - DEFAULT_EQ_SEL) : DEFAULT_EQ_SEL;
     342              : 
     343              :     /*
     344              :      * We can do a lot better if the something is a constant.  (Note: the
     345              :      * Const might result from estimation rather than being a simple constant
     346              :      * in the query.)
     347              :      */
     348       434150 :     if (IsA(other, Const))
     349       171066 :         selec = var_eq_const(&vardata, operator, collation,
     350       171066 :                              ((Const *) other)->constvalue,
     351       171066 :                              ((Const *) other)->constisnull,
     352              :                              varonleft, negate);
     353              :     else
     354       263084 :         selec = var_eq_non_const(&vardata, operator, collation, other,
     355              :                                  varonleft, negate);
     356              : 
     357       434150 :     ReleaseVariableStats(vardata);
     358              : 
     359       434150 :     return selec;
     360              : }
     361              : 
     362              : /*
     363              :  * var_eq_const --- eqsel for var = const case
     364              :  *
     365              :  * This is exported so that some other estimation functions can use it.
     366              :  */
     367              : double
     368       194867 : var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation,
     369              :              Datum constval, bool constisnull,
     370              :              bool varonleft, bool negate)
     371              : {
     372              :     double      selec;
     373       194867 :     double      nullfrac = 0.0;
     374              :     bool        isdefault;
     375              :     Oid         opfuncoid;
     376              : 
     377              :     /*
     378              :      * If the constant is NULL, assume operator is strict and return zero, ie,
     379              :      * operator will never return TRUE.  (It's zero even for a negator op.)
     380              :      */
     381       194867 :     if (constisnull)
     382          212 :         return 0.0;
     383              : 
     384              :     /*
     385              :      * Grab the nullfrac for use below.  Note we allow use of nullfrac
     386              :      * regardless of security check.
     387              :      */
     388       194655 :     if (HeapTupleIsValid(vardata->statsTuple))
     389              :     {
     390              :         Form_pg_statistic stats;
     391              : 
     392       141039 :         stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
     393       141039 :         nullfrac = stats->stanullfrac;
     394              :     }
     395              : 
     396              :     /*
     397              :      * If we matched the var to a unique index, DISTINCT or GROUP-BY clause,
     398              :      * assume there is exactly one match regardless of anything else.  (This
     399              :      * is slightly bogus, since the index or clause's equality operator might
     400              :      * be different from ours, but it's much more likely to be right than
     401              :      * ignoring the information.)
     402              :      */
     403       194655 :     if (vardata->isunique && vardata->rel && vardata->rel->tuples >= 1.0)
     404              :     {
     405        44121 :         selec = 1.0 / vardata->rel->tuples;
     406              :     }
     407       256635 :     else if (HeapTupleIsValid(vardata->statsTuple) &&
     408       106101 :              statistic_proc_security_check(vardata,
     409       106101 :                                            (opfuncoid = get_opcode(oproid))))
     410       106101 :     {
     411              :         AttStatsSlot sslot;
     412       106101 :         bool        match = false;
     413              :         int         i;
     414              : 
     415              :         /*
     416              :          * Is the constant "=" to any of the column's most common values?
     417              :          * (Although the given operator may not really be "=", we will assume
     418              :          * that seeing whether it returns TRUE is an appropriate test.  If you
     419              :          * don't like this, maybe you shouldn't be using eqsel for your
     420              :          * operator...)
     421              :          */
     422       106101 :         if (get_attstatsslot(&sslot, vardata->statsTuple,
     423              :                              STATISTIC_KIND_MCV, InvalidOid,
     424              :                              ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS))
     425              :         {
     426        94198 :             LOCAL_FCINFO(fcinfo, 2);
     427              :             FmgrInfo    eqproc;
     428              : 
     429        94198 :             fmgr_info(opfuncoid, &eqproc);
     430              : 
     431              :             /*
     432              :              * Save a few cycles by setting up the fcinfo struct just once.
     433              :              * Using FunctionCallInvoke directly also avoids failure if the
     434              :              * eqproc returns NULL, though really equality functions should
     435              :              * never do that.
     436              :              */
     437        94198 :             InitFunctionCallInfoData(*fcinfo, &eqproc, 2, collation,
     438              :                                      NULL, NULL);
     439        94198 :             fcinfo->args[0].isnull = false;
     440        94198 :             fcinfo->args[1].isnull = false;
     441              :             /* be careful to apply operator right way 'round */
     442        94198 :             if (varonleft)
     443        94182 :                 fcinfo->args[1].value = constval;
     444              :             else
     445           16 :                 fcinfo->args[0].value = constval;
     446              : 
     447      1481116 :             for (i = 0; i < sslot.nvalues; i++)
     448              :             {
     449              :                 Datum       fresult;
     450              : 
     451      1436165 :                 if (varonleft)
     452      1436137 :                     fcinfo->args[0].value = sslot.values[i];
     453              :                 else
     454           28 :                     fcinfo->args[1].value = sslot.values[i];
     455      1436165 :                 fcinfo->isnull = false;
     456      1436165 :                 fresult = FunctionCallInvoke(fcinfo);
     457      1436165 :                 if (!fcinfo->isnull && DatumGetBool(fresult))
     458              :                 {
     459        49247 :                     match = true;
     460        49247 :                     break;
     461              :                 }
     462              :             }
     463              :         }
     464              :         else
     465              :         {
     466              :             /* no most-common-value info available */
     467        11903 :             i = 0;              /* keep compiler quiet */
     468              :         }
     469              : 
     470       106101 :         if (match)
     471              :         {
     472              :             /*
     473              :              * Constant is "=" to this common value.  We know selectivity
     474              :              * exactly (or as exactly as ANALYZE could calculate it, anyway).
     475              :              */
     476        49247 :             selec = sslot.numbers[i];
     477              :         }
     478              :         else
     479              :         {
     480              :             /*
     481              :              * Comparison is against a constant that is neither NULL nor any
     482              :              * of the common values.  Its selectivity cannot be more than
     483              :              * this:
     484              :              */
     485        56854 :             double      sumcommon = 0.0;
     486              :             double      otherdistinct;
     487              : 
     488      1253988 :             for (i = 0; i < sslot.nnumbers; i++)
     489      1197134 :                 sumcommon += sslot.numbers[i];
     490        56854 :             selec = 1.0 - sumcommon - nullfrac;
     491        56854 :             CLAMP_PROBABILITY(selec);
     492              : 
     493              :             /*
     494              :              * and in fact it's probably a good deal less. We approximate that
     495              :              * all the not-common values share this remaining fraction
     496              :              * equally, so we divide by the number of other distinct values.
     497              :              */
     498        56854 :             otherdistinct = get_variable_numdistinct(vardata, &isdefault) -
     499        56854 :                 sslot.nnumbers;
     500        56854 :             if (otherdistinct > 1)
     501        26698 :                 selec /= otherdistinct;
     502              : 
     503              :             /*
     504              :              * Another cross-check: selectivity shouldn't be estimated as more
     505              :              * than the least common "most common value".
     506              :              */
     507        56854 :             if (sslot.nnumbers > 0 && selec > sslot.numbers[sslot.nnumbers - 1])
     508            0 :                 selec = sslot.numbers[sslot.nnumbers - 1];
     509              :         }
     510              : 
     511       106101 :         free_attstatsslot(&sslot);
     512              :     }
     513              :     else
     514              :     {
     515              :         /*
     516              :          * No ANALYZE stats available, so make a guess using estimated number
     517              :          * of distinct values and assuming they are equally common. (The guess
     518              :          * is unlikely to be very good, but we do know a few special cases.)
     519              :          */
     520        44433 :         selec = 1.0 / get_variable_numdistinct(vardata, &isdefault);
     521              :     }
     522              : 
     523              :     /* now adjust if we wanted <> rather than = */
     524       194655 :     if (negate)
     525        20421 :         selec = 1.0 - selec - nullfrac;
     526              : 
     527              :     /* result should be in range, but make sure... */
     528       194655 :     CLAMP_PROBABILITY(selec);
     529              : 
     530       194655 :     return selec;
     531              : }
     532              : 
     533              : /*
     534              :  * var_eq_non_const --- eqsel for var = something-other-than-const case
     535              :  *
     536              :  * This is exported so that some other estimation functions can use it.
     537              :  */
     538              : double
     539       263084 : var_eq_non_const(VariableStatData *vardata, Oid oproid, Oid collation,
     540              :                  Node *other,
     541              :                  bool varonleft, bool negate)
     542              : {
     543              :     double      selec;
     544       263084 :     double      nullfrac = 0.0;
     545              :     bool        isdefault;
     546              : 
     547              :     /*
     548              :      * Grab the nullfrac for use below.
     549              :      */
     550       263084 :     if (HeapTupleIsValid(vardata->statsTuple))
     551              :     {
     552              :         Form_pg_statistic stats;
     553              : 
     554       161650 :         stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
     555       161650 :         nullfrac = stats->stanullfrac;
     556              :     }
     557              : 
     558              :     /*
     559              :      * If we matched the var to a unique index, DISTINCT or GROUP-BY clause,
     560              :      * assume there is exactly one match regardless of anything else.  (This
     561              :      * is slightly bogus, since the index or clause's equality operator might
     562              :      * be different from ours, but it's much more likely to be right than
     563              :      * ignoring the information.)
     564              :      */
     565       263084 :     if (vardata->isunique && vardata->rel && vardata->rel->tuples >= 1.0)
     566              :     {
     567        92644 :         selec = 1.0 / vardata->rel->tuples;
     568              :     }
     569       170440 :     else if (HeapTupleIsValid(vardata->statsTuple))
     570              :     {
     571              :         double      ndistinct;
     572              :         AttStatsSlot sslot;
     573              : 
     574              :         /*
     575              :          * Search is for a value that we do not know a priori, but we will
     576              :          * assume it is not NULL.  Estimate the selectivity as non-null
     577              :          * fraction divided by number of distinct values, so that we get a
     578              :          * result averaged over all possible values whether common or
     579              :          * uncommon.  (Essentially, we are assuming that the not-yet-known
     580              :          * comparison value is equally likely to be any of the possible
     581              :          * values, regardless of their frequency in the table.  Is that a good
     582              :          * idea?)
     583              :          */
     584        80498 :         selec = 1.0 - nullfrac;
     585        80498 :         ndistinct = get_variable_numdistinct(vardata, &isdefault);
     586        80498 :         if (ndistinct > 1)
     587        78460 :             selec /= ndistinct;
     588              : 
     589              :         /*
     590              :          * Cross-check: selectivity should never be estimated as more than the
     591              :          * most common value's.
     592              :          */
     593        80498 :         if (get_attstatsslot(&sslot, vardata->statsTuple,
     594              :                              STATISTIC_KIND_MCV, InvalidOid,
     595              :                              ATTSTATSSLOT_NUMBERS))
     596              :         {
     597        70290 :             if (sslot.nnumbers > 0 && selec > sslot.numbers[0])
     598          291 :                 selec = sslot.numbers[0];
     599        70290 :             free_attstatsslot(&sslot);
     600              :         }
     601              :     }
     602              :     else
     603              :     {
     604              :         /*
     605              :          * No ANALYZE stats available, so make a guess using estimated number
     606              :          * of distinct values and assuming they are equally common. (The guess
     607              :          * is unlikely to be very good, but we do know a few special cases.)
     608              :          */
     609        89942 :         selec = 1.0 / get_variable_numdistinct(vardata, &isdefault);
     610              :     }
     611              : 
     612              :     /* now adjust if we wanted <> rather than = */
     613       263084 :     if (negate)
     614         3727 :         selec = 1.0 - selec - nullfrac;
     615              : 
     616              :     /* result should be in range, but make sure... */
     617       263084 :     CLAMP_PROBABILITY(selec);
     618              : 
     619       263084 :     return selec;
     620              : }
     621              : 
     622              : /*
     623              :  *      neqsel          - Selectivity of "!=" for any data types.
     624              :  *
     625              :  * This routine is also used for some operators that are not "!="
     626              :  * but have comparable selectivity behavior.  See above comments
     627              :  * for eqsel().
     628              :  */
     629              : Datum
     630        25485 : neqsel(PG_FUNCTION_ARGS)
     631              : {
     632        25485 :     PG_RETURN_FLOAT8((float8) eqsel_internal(fcinfo, true));
     633              : }
     634              : 
     635              : /*
     636              :  *  scalarineqsel       - Selectivity of "<", "<=", ">", ">=" for scalars.
     637              :  *
     638              :  * This is the guts of scalarltsel/scalarlesel/scalargtsel/scalargesel.
     639              :  * The isgt and iseq flags distinguish which of the four cases apply.
     640              :  *
     641              :  * The caller has commuted the clause, if necessary, so that we can treat
     642              :  * the variable as being on the left.  The caller must also make sure that
     643              :  * the other side of the clause is a non-null Const, and dissect that into
     644              :  * a value and datatype.  (This definition simplifies some callers that
     645              :  * want to estimate against a computed value instead of a Const node.)
     646              :  *
     647              :  * This routine works for any datatype (or pair of datatypes) known to
     648              :  * convert_to_scalar().  If it is applied to some other datatype,
     649              :  * it will return an approximate estimate based on assuming that the constant
     650              :  * value falls in the middle of the bin identified by binary search.
     651              :  */
     652              : static double
     653       200678 : scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq,
     654              :               Oid collation,
     655              :               VariableStatData *vardata, Datum constval, Oid consttype)
     656              : {
     657              :     Form_pg_statistic stats;
     658              :     FmgrInfo    opproc;
     659              :     double      mcv_selec,
     660              :                 hist_selec,
     661              :                 sumcommon;
     662              :     double      selec;
     663              : 
     664       200678 :     if (!HeapTupleIsValid(vardata->statsTuple))
     665              :     {
     666              :         /*
     667              :          * No stats are available.  Typically this means we have to fall back
     668              :          * on the default estimate; but if the variable is CTID then we can
     669              :          * make an estimate based on comparing the constant to the table size.
     670              :          */
     671        14322 :         if (vardata->var && IsA(vardata->var, Var) &&
     672        11838 :             ((Var *) vardata->var)->varattno == SelfItemPointerAttributeNumber)
     673              :         {
     674              :             ItemPointer itemptr;
     675              :             double      block;
     676              :             double      density;
     677              : 
     678              :             /*
     679              :              * If the relation's empty, we're going to include all of it.
     680              :              * (This is mostly to avoid divide-by-zero below.)
     681              :              */
     682         1010 :             if (vardata->rel->pages == 0)
     683            0 :                 return 1.0;
     684              : 
     685         1010 :             itemptr = (ItemPointer) DatumGetPointer(constval);
     686         1010 :             block = ItemPointerGetBlockNumberNoCheck(itemptr);
     687              : 
     688              :             /*
     689              :              * Determine the average number of tuples per page (density).
     690              :              *
     691              :              * Since the last page will, on average, be only half full, we can
     692              :              * estimate it to have half as many tuples as earlier pages.  So
     693              :              * give it half the weight of a regular page.
     694              :              */
     695         1010 :             density = vardata->rel->tuples / (vardata->rel->pages - 0.5);
     696              : 
     697              :             /* If target is the last page, use half the density. */
     698         1010 :             if (block >= vardata->rel->pages - 1)
     699           15 :                 density *= 0.5;
     700              : 
     701              :             /*
     702              :              * Using the average tuples per page, calculate how far into the
     703              :              * page the itemptr is likely to be and adjust block accordingly,
     704              :              * by adding that fraction of a whole block (but never more than a
     705              :              * whole block, no matter how high the itemptr's offset is).  Here
     706              :              * we are ignoring the possibility of dead-tuple line pointers,
     707              :              * which is fairly bogus, but we lack the info to do better.
     708              :              */
     709         1010 :             if (density > 0.0)
     710              :             {
     711         1010 :                 OffsetNumber offset = ItemPointerGetOffsetNumberNoCheck(itemptr);
     712              : 
     713         1010 :                 block += Min(offset / density, 1.0);
     714              :             }
     715              : 
     716              :             /*
     717              :              * Convert relative block number to selectivity.  Again, the last
     718              :              * page has only half weight.
     719              :              */
     720         1010 :             selec = block / (vardata->rel->pages - 0.5);
     721              : 
     722              :             /*
     723              :              * The calculation so far gave us a selectivity for the "<=" case.
     724              :              * We'll have one fewer tuple for "<" and one additional tuple for
     725              :              * ">=", the latter of which we'll reverse the selectivity for
     726              :              * below, so we can simply subtract one tuple for both cases.  The
     727              :              * cases that need this adjustment can be identified by iseq being
     728              :              * equal to isgt.
     729              :              */
     730         1010 :             if (iseq == isgt && vardata->rel->tuples >= 1.0)
     731          940 :                 selec -= (1.0 / vardata->rel->tuples);
     732              : 
     733              :             /* Finally, reverse the selectivity for the ">", ">=" cases. */
     734         1010 :             if (isgt)
     735          931 :                 selec = 1.0 - selec;
     736              : 
     737         1010 :             CLAMP_PROBABILITY(selec);
     738         1010 :             return selec;
     739              :         }
     740              : 
     741              :         /* no stats available, so default result */
     742        13312 :         return DEFAULT_INEQ_SEL;
     743              :     }
     744       186356 :     stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
     745              : 
     746       186356 :     fmgr_info(get_opcode(operator), &opproc);
     747              : 
     748              :     /*
     749              :      * If we have most-common-values info, add up the fractions of the MCV
     750              :      * entries that satisfy MCV OP CONST.  These fractions contribute directly
     751              :      * to the result selectivity.  Also add up the total fraction represented
     752              :      * by MCV entries.
     753              :      */
     754       186356 :     mcv_selec = mcv_selectivity(vardata, &opproc, collation, constval, true,
     755              :                                 &sumcommon);
     756              : 
     757              :     /*
     758              :      * If there is a histogram, determine which bin the constant falls in, and
     759              :      * compute the resulting contribution to selectivity.
     760              :      */
     761       186356 :     hist_selec = ineq_histogram_selectivity(root, vardata,
     762              :                                             operator, &opproc, isgt, iseq,
     763              :                                             collation,
     764              :                                             constval, consttype);
     765              : 
     766              :     /*
     767              :      * Now merge the results from the MCV and histogram calculations,
     768              :      * realizing that the histogram covers only the non-null values that are
     769              :      * not listed in MCV.
     770              :      */
     771       186356 :     selec = 1.0 - stats->stanullfrac - sumcommon;
     772              : 
     773       186356 :     if (hist_selec >= 0.0)
     774       117714 :         selec *= hist_selec;
     775              :     else
     776              :     {
     777              :         /*
     778              :          * If no histogram but there are values not accounted for by MCV,
     779              :          * arbitrarily assume half of them will match.
     780              :          */
     781        68642 :         selec *= 0.5;
     782              :     }
     783              : 
     784       186356 :     selec += mcv_selec;
     785              : 
     786              :     /* result should be in range, but make sure... */
     787       186356 :     CLAMP_PROBABILITY(selec);
     788              : 
     789       186356 :     return selec;
     790              : }
     791              : 
     792              : /*
     793              :  *  mcv_selectivity         - Examine the MCV list for selectivity estimates
     794              :  *
     795              :  * Determine the fraction of the variable's MCV population that satisfies
     796              :  * the predicate (VAR OP CONST), or (CONST OP VAR) if !varonleft.  Also
     797              :  * compute the fraction of the total column population represented by the MCV
     798              :  * list.  This code will work for any boolean-returning predicate operator.
     799              :  *
     800              :  * The function result is the MCV selectivity, and the fraction of the
     801              :  * total population is returned into *sumcommonp.  Zeroes are returned
     802              :  * if there is no MCV list.
     803              :  */
     804              : double
     805       189548 : mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation,
     806              :                 Datum constval, bool varonleft,
     807              :                 double *sumcommonp)
     808              : {
     809              :     double      mcv_selec,
     810              :                 sumcommon;
     811              :     AttStatsSlot sslot;
     812              :     int         i;
     813              : 
     814       189548 :     mcv_selec = 0.0;
     815       189548 :     sumcommon = 0.0;
     816              : 
     817       377870 :     if (HeapTupleIsValid(vardata->statsTuple) &&
     818       376479 :         statistic_proc_security_check(vardata, opproc->fn_oid) &&
     819       188157 :         get_attstatsslot(&sslot, vardata->statsTuple,
     820              :                          STATISTIC_KIND_MCV, InvalidOid,
     821              :                          ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS))
     822              :     {
     823       103139 :         LOCAL_FCINFO(fcinfo, 2);
     824              : 
     825              :         /*
     826              :          * We invoke the opproc "by hand" so that we won't fail on NULL
     827              :          * results.  Such cases won't arise for normal comparison functions,
     828              :          * but generic_restriction_selectivity could perhaps be used with
     829              :          * operators that can return NULL.  A small side benefit is to not
     830              :          * need to re-initialize the fcinfo struct from scratch each time.
     831              :          */
     832       103139 :         InitFunctionCallInfoData(*fcinfo, opproc, 2, collation,
     833              :                                  NULL, NULL);
     834       103139 :         fcinfo->args[0].isnull = false;
     835       103139 :         fcinfo->args[1].isnull = false;
     836              :         /* be careful to apply operator right way 'round */
     837       103139 :         if (varonleft)
     838       103139 :             fcinfo->args[1].value = constval;
     839              :         else
     840            0 :             fcinfo->args[0].value = constval;
     841              : 
     842      2522823 :         for (i = 0; i < sslot.nvalues; i++)
     843              :         {
     844              :             Datum       fresult;
     845              : 
     846      2419684 :             if (varonleft)
     847      2419684 :                 fcinfo->args[0].value = sslot.values[i];
     848              :             else
     849            0 :                 fcinfo->args[1].value = sslot.values[i];
     850      2419684 :             fcinfo->isnull = false;
     851      2419684 :             fresult = FunctionCallInvoke(fcinfo);
     852      2419684 :             if (!fcinfo->isnull && DatumGetBool(fresult))
     853       932846 :                 mcv_selec += sslot.numbers[i];
     854      2419684 :             sumcommon += sslot.numbers[i];
     855              :         }
     856       103139 :         free_attstatsslot(&sslot);
     857              :     }
     858              : 
     859       189548 :     *sumcommonp = sumcommon;
     860       189548 :     return mcv_selec;
     861              : }
     862              : 
     863              : /*
     864              :  *  histogram_selectivity   - Examine the histogram for selectivity estimates
     865              :  *
     866              :  * Determine the fraction of the variable's histogram entries that satisfy
     867              :  * the predicate (VAR OP CONST), or (CONST OP VAR) if !varonleft.
     868              :  *
     869              :  * This code will work for any boolean-returning predicate operator, whether
     870              :  * or not it has anything to do with the histogram sort operator.  We are
     871              :  * essentially using the histogram just as a representative sample.  However,
     872              :  * small histograms are unlikely to be all that representative, so the caller
     873              :  * should be prepared to fall back on some other estimation approach when the
     874              :  * histogram is missing or very small.  It may also be prudent to combine this
     875              :  * approach with another one when the histogram is small.
     876              :  *
     877              :  * If the actual histogram size is not at least min_hist_size, we won't bother
     878              :  * to do the calculation at all.  Also, if the n_skip parameter is > 0, we
     879              :  * ignore the first and last n_skip histogram elements, on the grounds that
     880              :  * they are outliers and hence not very representative.  Typical values for
     881              :  * these parameters are 10 and 1.
     882              :  *
     883              :  * The function result is the selectivity, or -1 if there is no histogram
     884              :  * or it's smaller than min_hist_size.
     885              :  *
     886              :  * The output parameter *hist_size receives the actual histogram size,
     887              :  * or zero if no histogram.  Callers may use this number to decide how
     888              :  * much faith to put in the function result.
     889              :  *
     890              :  * Note that the result disregards both the most-common-values (if any) and
     891              :  * null entries.  The caller is expected to combine this result with
     892              :  * statistics for those portions of the column population.  It may also be
     893              :  * prudent to clamp the result range, ie, disbelieve exact 0 or 1 outputs.
     894              :  */
     895              : double
     896         3192 : histogram_selectivity(VariableStatData *vardata,
     897              :                       FmgrInfo *opproc, Oid collation,
     898              :                       Datum constval, bool varonleft,
     899              :                       int min_hist_size, int n_skip,
     900              :                       int *hist_size)
     901              : {
     902              :     double      result;
     903              :     AttStatsSlot sslot;
     904              : 
     905              :     /* check sanity of parameters */
     906              :     Assert(n_skip >= 0);
     907              :     Assert(min_hist_size > 2 * n_skip);
     908              : 
     909         5158 :     if (HeapTupleIsValid(vardata->statsTuple) &&
     910         3929 :         statistic_proc_security_check(vardata, opproc->fn_oid) &&
     911         1963 :         get_attstatsslot(&sslot, vardata->statsTuple,
     912              :                          STATISTIC_KIND_HISTOGRAM, InvalidOid,
     913              :                          ATTSTATSSLOT_VALUES))
     914              :     {
     915         1915 :         *hist_size = sslot.nvalues;
     916         1915 :         if (sslot.nvalues >= min_hist_size)
     917              :         {
     918          892 :             LOCAL_FCINFO(fcinfo, 2);
     919          892 :             int         nmatch = 0;
     920              :             int         i;
     921              : 
     922              :             /*
     923              :              * We invoke the opproc "by hand" so that we won't fail on NULL
     924              :              * results.  Such cases won't arise for normal comparison
     925              :              * functions, but generic_restriction_selectivity could perhaps be
     926              :              * used with operators that can return NULL.  A small side benefit
     927              :              * is to not need to re-initialize the fcinfo struct from scratch
     928              :              * each time.
     929              :              */
     930          892 :             InitFunctionCallInfoData(*fcinfo, opproc, 2, collation,
     931              :                                      NULL, NULL);
     932          892 :             fcinfo->args[0].isnull = false;
     933          892 :             fcinfo->args[1].isnull = false;
     934              :             /* be careful to apply operator right way 'round */
     935          892 :             if (varonleft)
     936          892 :                 fcinfo->args[1].value = constval;
     937              :             else
     938            0 :                 fcinfo->args[0].value = constval;
     939              : 
     940        70904 :             for (i = n_skip; i < sslot.nvalues - n_skip; i++)
     941              :             {
     942              :                 Datum       fresult;
     943              : 
     944        70012 :                 if (varonleft)
     945        70012 :                     fcinfo->args[0].value = sslot.values[i];
     946              :                 else
     947            0 :                     fcinfo->args[1].value = sslot.values[i];
     948        70012 :                 fcinfo->isnull = false;
     949        70012 :                 fresult = FunctionCallInvoke(fcinfo);
     950        70012 :                 if (!fcinfo->isnull && DatumGetBool(fresult))
     951         3974 :                     nmatch++;
     952              :             }
     953          892 :             result = ((double) nmatch) / ((double) (sslot.nvalues - 2 * n_skip));
     954              :         }
     955              :         else
     956         1023 :             result = -1;
     957         1915 :         free_attstatsslot(&sslot);
     958              :     }
     959              :     else
     960              :     {
     961         1277 :         *hist_size = 0;
     962         1277 :         result = -1;
     963              :     }
     964              : 
     965         3192 :     return result;
     966              : }
     967              : 
     968              : /*
     969              :  *  generic_restriction_selectivity     - Selectivity for almost anything
     970              :  *
     971              :  * This function estimates selectivity for operators that we don't have any
     972              :  * special knowledge about, but are on data types that we collect standard
     973              :  * MCV and/or histogram statistics for.  (Additional assumptions are that
     974              :  * the operator is strict and immutable, or at least stable.)
     975              :  *
     976              :  * If we have "VAR OP CONST" or "CONST OP VAR", selectivity is estimated by
     977              :  * applying the operator to each element of the column's MCV and/or histogram
     978              :  * stats, and merging the results using the assumption that the histogram is
     979              :  * a reasonable random sample of the column's non-MCV population.  Note that
     980              :  * if the operator's semantics are related to the histogram ordering, this
     981              :  * might not be such a great assumption; other functions such as
     982              :  * scalarineqsel() are probably a better match in such cases.
     983              :  *
     984              :  * Otherwise, fall back to the default selectivity provided by the caller.
     985              :  */
     986              : double
     987          565 : generic_restriction_selectivity(PlannerInfo *root, Oid oproid, Oid collation,
     988              :                                 List *args, int varRelid,
     989              :                                 double default_selectivity)
     990              : {
     991              :     double      selec;
     992              :     VariableStatData vardata;
     993              :     Node       *other;
     994              :     bool        varonleft;
     995              : 
     996              :     /*
     997              :      * If expression is not variable OP something or something OP variable,
     998              :      * then punt and return the default estimate.
     999              :      */
    1000          565 :     if (!get_restriction_variable(root, args, varRelid,
    1001              :                                   &vardata, &other, &varonleft))
    1002            0 :         return default_selectivity;
    1003              : 
    1004              :     /*
    1005              :      * If the something is a NULL constant, assume operator is strict and
    1006              :      * return zero, ie, operator will never return TRUE.
    1007              :      */
    1008          565 :     if (IsA(other, Const) &&
    1009          565 :         ((Const *) other)->constisnull)
    1010              :     {
    1011            0 :         ReleaseVariableStats(vardata);
    1012            0 :         return 0.0;
    1013              :     }
    1014              : 
    1015          565 :     if (IsA(other, Const))
    1016              :     {
    1017              :         /* Variable is being compared to a known non-null constant */
    1018          565 :         Datum       constval = ((Const *) other)->constvalue;
    1019              :         FmgrInfo    opproc;
    1020              :         double      mcvsum;
    1021              :         double      mcvsel;
    1022              :         double      nullfrac;
    1023              :         int         hist_size;
    1024              : 
    1025          565 :         fmgr_info(get_opcode(oproid), &opproc);
    1026              : 
    1027              :         /*
    1028              :          * Calculate the selectivity for the column's most common values.
    1029              :          */
    1030          565 :         mcvsel = mcv_selectivity(&vardata, &opproc, collation,
    1031              :                                  constval, varonleft,
    1032              :                                  &mcvsum);
    1033              : 
    1034              :         /*
    1035              :          * If the histogram is large enough, see what fraction of it matches
    1036              :          * the query, and assume that's representative of the non-MCV
    1037              :          * population.  Otherwise use the default selectivity for the non-MCV
    1038              :          * population.
    1039              :          */
    1040          565 :         selec = histogram_selectivity(&vardata, &opproc, collation,
    1041              :                                       constval, varonleft,
    1042              :                                       10, 1, &hist_size);
    1043          565 :         if (selec < 0)
    1044              :         {
    1045              :             /* Nope, fall back on default */
    1046          565 :             selec = default_selectivity;
    1047              :         }
    1048            0 :         else if (hist_size < 100)
    1049              :         {
    1050              :             /*
    1051              :              * For histogram sizes from 10 to 100, we combine the histogram
    1052              :              * and default selectivities, putting increasingly more trust in
    1053              :              * the histogram for larger sizes.
    1054              :              */
    1055            0 :             double      hist_weight = hist_size / 100.0;
    1056              : 
    1057            0 :             selec = selec * hist_weight +
    1058            0 :                 default_selectivity * (1.0 - hist_weight);
    1059              :         }
    1060              : 
    1061              :         /* In any case, don't believe extremely small or large estimates. */
    1062          565 :         if (selec < 0.0001)
    1063            0 :             selec = 0.0001;
    1064          565 :         else if (selec > 0.9999)
    1065            0 :             selec = 0.9999;
    1066              : 
    1067              :         /* Don't forget to account for nulls. */
    1068          565 :         if (HeapTupleIsValid(vardata.statsTuple))
    1069           42 :             nullfrac = ((Form_pg_statistic) GETSTRUCT(vardata.statsTuple))->stanullfrac;
    1070              :         else
    1071          523 :             nullfrac = 0.0;
    1072              : 
    1073              :         /*
    1074              :          * Now merge the results from the MCV and histogram calculations,
    1075              :          * realizing that the histogram covers only the non-null values that
    1076              :          * are not listed in MCV.
    1077              :          */
    1078          565 :         selec *= 1.0 - nullfrac - mcvsum;
    1079          565 :         selec += mcvsel;
    1080              :     }
    1081              :     else
    1082              :     {
    1083              :         /* Comparison value is not constant, so we can't do anything */
    1084            0 :         selec = default_selectivity;
    1085              :     }
    1086              : 
    1087          565 :     ReleaseVariableStats(vardata);
    1088              : 
    1089              :     /* result should be in range, but make sure... */
    1090          565 :     CLAMP_PROBABILITY(selec);
    1091              : 
    1092          565 :     return selec;
    1093              : }
    1094              : 
    1095              : /*
    1096              :  *  ineq_histogram_selectivity  - Examine the histogram for scalarineqsel
    1097              :  *
    1098              :  * Determine the fraction of the variable's histogram population that
    1099              :  * satisfies the inequality condition, ie, VAR < (or <=, >, >=) CONST.
    1100              :  * The isgt and iseq flags distinguish which of the four cases apply.
    1101              :  *
    1102              :  * While opproc could be looked up from the operator OID, common callers
    1103              :  * also need to call it separately, so we make the caller pass both.
    1104              :  *
    1105              :  * Returns -1 if there is no histogram (valid results will always be >= 0).
    1106              :  *
    1107              :  * Note that the result disregards both the most-common-values (if any) and
    1108              :  * null entries.  The caller is expected to combine this result with
    1109              :  * statistics for those portions of the column population.
    1110              :  *
    1111              :  * This is exported so that some other estimation functions can use it.
    1112              :  */
    1113              : double
    1114       189157 : ineq_histogram_selectivity(PlannerInfo *root,
    1115              :                            VariableStatData *vardata,
    1116              :                            Oid opoid, FmgrInfo *opproc, bool isgt, bool iseq,
    1117              :                            Oid collation,
    1118              :                            Datum constval, Oid consttype)
    1119              : {
    1120              :     double      hist_selec;
    1121              :     AttStatsSlot sslot;
    1122              : 
    1123       189157 :     hist_selec = -1.0;
    1124              : 
    1125              :     /*
    1126              :      * Someday, ANALYZE might store more than one histogram per rel/att,
    1127              :      * corresponding to more than one possible sort ordering defined for the
    1128              :      * column type.  Right now, we know there is only one, so just grab it and
    1129              :      * see if it matches the query.
    1130              :      *
    1131              :      * Note that we can't use opoid as search argument; the staop appearing in
    1132              :      * pg_statistic will be for the relevant '<' operator, but what we have
    1133              :      * might be some other inequality operator such as '>='.  (Even if opoid
    1134              :      * is a '<' operator, it could be cross-type.)  Hence we must use
    1135              :      * comparison_ops_are_compatible() to see if the operators match.
    1136              :      */
    1137       377973 :     if (HeapTupleIsValid(vardata->statsTuple) &&
    1138       377470 :         statistic_proc_security_check(vardata, opproc->fn_oid) &&
    1139       188654 :         get_attstatsslot(&sslot, vardata->statsTuple,
    1140              :                          STATISTIC_KIND_HISTOGRAM, InvalidOid,
    1141              :                          ATTSTATSSLOT_VALUES))
    1142              :     {
    1143       120172 :         if (sslot.nvalues > 1 &&
    1144       240306 :             sslot.stacoll == collation &&
    1145       120134 :             comparison_ops_are_compatible(sslot.staop, opoid))
    1146       120080 :         {
    1147              :             /*
    1148              :              * Use binary search to find the desired location, namely the
    1149              :              * right end of the histogram bin containing the comparison value,
    1150              :              * which is the leftmost entry for which the comparison operator
    1151              :              * succeeds (if isgt) or fails (if !isgt).
    1152              :              *
    1153              :              * In this loop, we pay no attention to whether the operator iseq
    1154              :              * or not; that detail will be mopped up below.  (We cannot tell,
    1155              :              * anyway, whether the operator thinks the values are equal.)
    1156              :              *
    1157              :              * If the binary search accesses the first or last histogram
    1158              :              * entry, we try to replace that endpoint with the true column min
    1159              :              * or max as found by get_actual_variable_range().  This
    1160              :              * ameliorates misestimates when the min or max is moving as a
    1161              :              * result of changes since the last ANALYZE.  Note that this could
    1162              :              * result in effectively including MCVs into the histogram that
    1163              :              * weren't there before, but we don't try to correct for that.
    1164              :              */
    1165              :             double      histfrac;
    1166       120080 :             int         lobound = 0;    /* first possible slot to search */
    1167       120080 :             int         hibound = sslot.nvalues;    /* last+1 slot to search */
    1168       120080 :             bool        have_end = false;
    1169              : 
    1170              :             /*
    1171              :              * If there are only two histogram entries, we'll want up-to-date
    1172              :              * values for both.  (If there are more than two, we need at most
    1173              :              * one of them to be updated, so we deal with that within the
    1174              :              * loop.)
    1175              :              */
    1176       120080 :             if (sslot.nvalues == 2)
    1177         2535 :                 have_end = get_actual_variable_range(root,
    1178              :                                                      vardata,
    1179              :                                                      sslot.staop,
    1180              :                                                      collation,
    1181              :                                                      &sslot.values[0],
    1182         2535 :                                                      &sslot.values[1]);
    1183              : 
    1184       783749 :             while (lobound < hibound)
    1185              :             {
    1186       663669 :                 int         probe = (lobound + hibound) / 2;
    1187              :                 bool        ltcmp;
    1188              : 
    1189              :                 /*
    1190              :                  * If we find ourselves about to compare to the first or last
    1191              :                  * histogram entry, first try to replace it with the actual
    1192              :                  * current min or max (unless we already did so above).
    1193              :                  */
    1194       663669 :                 if (probe == 0 && sslot.nvalues > 2)
    1195        58487 :                     have_end = get_actual_variable_range(root,
    1196              :                                                          vardata,
    1197              :                                                          sslot.staop,
    1198              :                                                          collation,
    1199              :                                                          &sslot.values[0],
    1200              :                                                          NULL);
    1201       605182 :                 else if (probe == sslot.nvalues - 1 && sslot.nvalues > 2)
    1202        40723 :                     have_end = get_actual_variable_range(root,
    1203              :                                                          vardata,
    1204              :                                                          sslot.staop,
    1205              :                                                          collation,
    1206              :                                                          NULL,
    1207        40723 :                                                          &sslot.values[probe]);
    1208              : 
    1209       663669 :                 ltcmp = DatumGetBool(FunctionCall2Coll(opproc,
    1210              :                                                        collation,
    1211       663669 :                                                        sslot.values[probe],
    1212              :                                                        constval));
    1213       663669 :                 if (isgt)
    1214        35638 :                     ltcmp = !ltcmp;
    1215       663669 :                 if (ltcmp)
    1216       253030 :                     lobound = probe + 1;
    1217              :                 else
    1218       410639 :                     hibound = probe;
    1219              :             }
    1220              : 
    1221       120080 :             if (lobound <= 0)
    1222              :             {
    1223              :                 /*
    1224              :                  * Constant is below lower histogram boundary.  More
    1225              :                  * precisely, we have found that no entry in the histogram
    1226              :                  * satisfies the inequality clause (if !isgt) or they all do
    1227              :                  * (if isgt).  We estimate that that's true of the entire
    1228              :                  * table, so set histfrac to 0.0 (which we'll flip to 1.0
    1229              :                  * below, if isgt).
    1230              :                  */
    1231        51370 :                 histfrac = 0.0;
    1232              :             }
    1233        68710 :             else if (lobound >= sslot.nvalues)
    1234              :             {
    1235              :                 /*
    1236              :                  * Inverse case: constant is above upper histogram boundary.
    1237              :                  */
    1238        19740 :                 histfrac = 1.0;
    1239              :             }
    1240              :             else
    1241              :             {
    1242              :                 /* We have values[i-1] <= constant <= values[i]. */
    1243        48970 :                 int         i = lobound;
    1244        48970 :                 double      eq_selec = 0;
    1245              :                 double      val,
    1246              :                             high,
    1247              :                             low;
    1248              :                 double      binfrac;
    1249              : 
    1250              :                 /*
    1251              :                  * In the cases where we'll need it below, obtain an estimate
    1252              :                  * of the selectivity of "x = constval".  We use a calculation
    1253              :                  * similar to what var_eq_const() does for a non-MCV constant,
    1254              :                  * ie, estimate that all distinct non-MCV values occur equally
    1255              :                  * often.  But multiplication by "1.0 - sumcommon - nullfrac"
    1256              :                  * will be done by our caller, so we shouldn't do that here.
    1257              :                  * Therefore we can't try to clamp the estimate by reference
    1258              :                  * to the least common MCV; the result would be too small.
    1259              :                  *
    1260              :                  * Note: since this is effectively assuming that constval
    1261              :                  * isn't an MCV, it's logically dubious if constval in fact is
    1262              :                  * one.  But we have to apply *some* correction for equality,
    1263              :                  * and anyway we cannot tell if constval is an MCV, since we
    1264              :                  * don't have a suitable equality operator at hand.
    1265              :                  */
    1266        48970 :                 if (i == 1 || isgt == iseq)
    1267              :                 {
    1268              :                     double      otherdistinct;
    1269              :                     bool        isdefault;
    1270              :                     AttStatsSlot mcvslot;
    1271              : 
    1272              :                     /* Get estimated number of distinct values */
    1273        20581 :                     otherdistinct = get_variable_numdistinct(vardata,
    1274              :                                                              &isdefault);
    1275              : 
    1276              :                     /* Subtract off the number of known MCVs */
    1277        20581 :                     if (get_attstatsslot(&mcvslot, vardata->statsTuple,
    1278              :                                          STATISTIC_KIND_MCV, InvalidOid,
    1279              :                                          ATTSTATSSLOT_NUMBERS))
    1280              :                     {
    1281         2592 :                         otherdistinct -= mcvslot.nnumbers;
    1282         2592 :                         free_attstatsslot(&mcvslot);
    1283              :                     }
    1284              : 
    1285              :                     /* If result doesn't seem sane, leave eq_selec at 0 */
    1286        20581 :                     if (otherdistinct > 1)
    1287        20560 :                         eq_selec = 1.0 / otherdistinct;
    1288              :                 }
    1289              : 
    1290              :                 /*
    1291              :                  * Convert the constant and the two nearest bin boundary
    1292              :                  * values to a uniform comparison scale, and do a linear
    1293              :                  * interpolation within this bin.
    1294              :                  */
    1295        48970 :                 if (convert_to_scalar(constval, consttype, collation,
    1296              :                                       &val,
    1297        48970 :                                       sslot.values[i - 1], sslot.values[i],
    1298              :                                       vardata->vartype,
    1299              :                                       &low, &high))
    1300              :                 {
    1301        48970 :                     if (high <= low)
    1302              :                     {
    1303              :                         /* cope if bin boundaries appear identical */
    1304            0 :                         binfrac = 0.5;
    1305              :                     }
    1306        48970 :                     else if (val <= low)
    1307        10989 :                         binfrac = 0.0;
    1308        37981 :                     else if (val >= high)
    1309         1632 :                         binfrac = 1.0;
    1310              :                     else
    1311              :                     {
    1312        36349 :                         binfrac = (val - low) / (high - low);
    1313              : 
    1314              :                         /*
    1315              :                          * Watch out for the possibility that we got a NaN or
    1316              :                          * Infinity from the division.  This can happen
    1317              :                          * despite the previous checks, if for example "low"
    1318              :                          * is -Infinity.
    1319              :                          */
    1320        36349 :                         if (isnan(binfrac) ||
    1321        36349 :                             binfrac < 0.0 || binfrac > 1.0)
    1322            0 :                             binfrac = 0.5;
    1323              :                     }
    1324              :                 }
    1325              :                 else
    1326              :                 {
    1327              :                     /*
    1328              :                      * Ideally we'd produce an error here, on the grounds that
    1329              :                      * the given operator shouldn't have scalarXXsel
    1330              :                      * registered as its selectivity func unless we can deal
    1331              :                      * with its operand types.  But currently, all manner of
    1332              :                      * stuff is invoking scalarXXsel, so give a default
    1333              :                      * estimate until that can be fixed.
    1334              :                      */
    1335            0 :                     binfrac = 0.5;
    1336              :                 }
    1337              : 
    1338              :                 /*
    1339              :                  * Now, compute the overall selectivity across the values
    1340              :                  * represented by the histogram.  We have i-1 full bins and
    1341              :                  * binfrac partial bin below the constant.
    1342              :                  */
    1343        48970 :                 histfrac = (double) (i - 1) + binfrac;
    1344        48970 :                 histfrac /= (double) (sslot.nvalues - 1);
    1345              : 
    1346              :                 /*
    1347              :                  * At this point, histfrac is an estimate of the fraction of
    1348              :                  * the population represented by the histogram that satisfies
    1349              :                  * "x <= constval".  Somewhat remarkably, this statement is
    1350              :                  * true regardless of which operator we were doing the probes
    1351              :                  * with, so long as convert_to_scalar() delivers reasonable
    1352              :                  * results.  If the probe constant is equal to some histogram
    1353              :                  * entry, we would have considered the bin to the left of that
    1354              :                  * entry if probing with "<" or ">=", or the bin to the right
    1355              :                  * if probing with "<=" or ">"; but binfrac would have come
    1356              :                  * out as 1.0 in the first case and 0.0 in the second, leading
    1357              :                  * to the same histfrac in either case.  For probe constants
    1358              :                  * between histogram entries, we find the same bin and get the
    1359              :                  * same estimate with any operator.
    1360              :                  *
    1361              :                  * The fact that the estimate corresponds to "x <= constval"
    1362              :                  * and not "x < constval" is because of the way that ANALYZE
    1363              :                  * constructs the histogram: each entry is, effectively, the
    1364              :                  * rightmost value in its sample bucket.  So selectivity
    1365              :                  * values that are exact multiples of 1/(histogram_size-1)
    1366              :                  * should be understood as estimates including a histogram
    1367              :                  * entry plus everything to its left.
    1368              :                  *
    1369              :                  * However, that breaks down for the first histogram entry,
    1370              :                  * which necessarily is the leftmost value in its sample
    1371              :                  * bucket.  That means the first histogram bin is slightly
    1372              :                  * narrower than the rest, by an amount equal to eq_selec.
    1373              :                  * Another way to say that is that we want "x <= leftmost" to
    1374              :                  * be estimated as eq_selec not zero.  So, if we're dealing
    1375              :                  * with the first bin (i==1), rescale to make that true while
    1376              :                  * adjusting the rest of that bin linearly.
    1377              :                  */
    1378        48970 :                 if (i == 1)
    1379         9166 :                     histfrac += eq_selec * (1.0 - binfrac);
    1380              : 
    1381              :                 /*
    1382              :                  * "x <= constval" is good if we want an estimate for "<=" or
    1383              :                  * ">", but if we are estimating for "<" or ">=", we now need
    1384              :                  * to decrease the estimate by eq_selec.
    1385              :                  */
    1386        48970 :                 if (isgt == iseq)
    1387        15360 :                     histfrac -= eq_selec;
    1388              :             }
    1389              : 
    1390              :             /*
    1391              :              * Now the estimate is finished for "<" and "<=" cases.  If we are
    1392              :              * estimating for ">" or ">=", flip it.
    1393              :              */
    1394       120080 :             hist_selec = isgt ? (1.0 - histfrac) : histfrac;
    1395              : 
    1396              :             /*
    1397              :              * The histogram boundaries are only approximate to begin with,
    1398              :              * and may well be out of date anyway.  Therefore, don't believe
    1399              :              * extremely small or large selectivity estimates --- unless we
    1400              :              * got actual current endpoint values from the table, in which
    1401              :              * case just do the usual sanity clamp.  Somewhat arbitrarily, we
    1402              :              * set the cutoff for other cases at a hundredth of the histogram
    1403              :              * resolution.
    1404              :              */
    1405       120080 :             if (have_end)
    1406        67841 :                 CLAMP_PROBABILITY(hist_selec);
    1407              :             else
    1408              :             {
    1409        52239 :                 double      cutoff = 0.01 / (double) (sslot.nvalues - 1);
    1410              : 
    1411        52239 :                 if (hist_selec < cutoff)
    1412        18514 :                     hist_selec = cutoff;
    1413        33725 :                 else if (hist_selec > 1.0 - cutoff)
    1414        11507 :                     hist_selec = 1.0 - cutoff;
    1415              :             }
    1416              :         }
    1417           92 :         else if (sslot.nvalues > 1)
    1418              :         {
    1419              :             /*
    1420              :              * If we get here, we have a histogram but it's not sorted the way
    1421              :              * we want.  Do a brute-force search to see how many of the
    1422              :              * entries satisfy the comparison condition, and take that
    1423              :              * fraction as our estimate.  (This is identical to the inner loop
    1424              :              * of histogram_selectivity; maybe share code?)
    1425              :              */
    1426           92 :             LOCAL_FCINFO(fcinfo, 2);
    1427           92 :             int         nmatch = 0;
    1428              : 
    1429           92 :             InitFunctionCallInfoData(*fcinfo, opproc, 2, collation,
    1430              :                                      NULL, NULL);
    1431           92 :             fcinfo->args[0].isnull = false;
    1432           92 :             fcinfo->args[1].isnull = false;
    1433           92 :             fcinfo->args[1].value = constval;
    1434       481050 :             for (int i = 0; i < sslot.nvalues; i++)
    1435              :             {
    1436              :                 Datum       fresult;
    1437              : 
    1438       480958 :                 fcinfo->args[0].value = sslot.values[i];
    1439       480958 :                 fcinfo->isnull = false;
    1440       480958 :                 fresult = FunctionCallInvoke(fcinfo);
    1441       480958 :                 if (!fcinfo->isnull && DatumGetBool(fresult))
    1442          966 :                     nmatch++;
    1443              :             }
    1444           92 :             hist_selec = ((double) nmatch) / ((double) sslot.nvalues);
    1445              : 
    1446              :             /*
    1447              :              * As above, clamp to a hundredth of the histogram resolution.
    1448              :              * This case is surely even less trustworthy than the normal one,
    1449              :              * so we shouldn't believe exact 0 or 1 selectivity.  (Maybe the
    1450              :              * clamp should be more restrictive in this case?)
    1451              :              */
    1452              :             {
    1453           92 :                 double      cutoff = 0.01 / (double) (sslot.nvalues - 1);
    1454              : 
    1455           92 :                 if (hist_selec < cutoff)
    1456            6 :                     hist_selec = cutoff;
    1457           86 :                 else if (hist_selec > 1.0 - cutoff)
    1458            6 :                     hist_selec = 1.0 - cutoff;
    1459              :             }
    1460              :         }
    1461              : 
    1462       120172 :         free_attstatsslot(&sslot);
    1463              :     }
    1464              : 
    1465       189157 :     return hist_selec;
    1466              : }
    1467              : 
    1468              : /*
    1469              :  * Common wrapper function for the selectivity estimators that simply
    1470              :  * invoke scalarineqsel().
    1471              :  */
    1472              : static Datum
    1473        26002 : scalarineqsel_wrapper(PG_FUNCTION_ARGS, bool isgt, bool iseq)
    1474              : {
    1475        26002 :     PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
    1476        26002 :     Oid         operator = PG_GETARG_OID(1);
    1477        26002 :     List       *args = (List *) PG_GETARG_POINTER(2);
    1478        26002 :     int         varRelid = PG_GETARG_INT32(3);
    1479        26002 :     Oid         collation = PG_GET_COLLATION();
    1480              :     VariableStatData vardata;
    1481              :     Node       *other;
    1482              :     bool        varonleft;
    1483              :     Datum       constval;
    1484              :     Oid         consttype;
    1485              :     double      selec;
    1486              : 
    1487              :     /*
    1488              :      * If expression is not variable op something or something op variable,
    1489              :      * then punt and return a default estimate.
    1490              :      */
    1491        26002 :     if (!get_restriction_variable(root, args, varRelid,
    1492              :                                   &vardata, &other, &varonleft))
    1493          322 :         PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    1494              : 
    1495              :     /*
    1496              :      * Can't do anything useful if the something is not a constant, either.
    1497              :      */
    1498        25680 :     if (!IsA(other, Const))
    1499              :     {
    1500         1421 :         ReleaseVariableStats(vardata);
    1501         1421 :         PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    1502              :     }
    1503              : 
    1504              :     /*
    1505              :      * If the constant is NULL, assume operator is strict and return zero, ie,
    1506              :      * operator will never return TRUE.
    1507              :      */
    1508        24259 :     if (((Const *) other)->constisnull)
    1509              :     {
    1510           33 :         ReleaseVariableStats(vardata);
    1511           33 :         PG_RETURN_FLOAT8(0.0);
    1512              :     }
    1513        24226 :     constval = ((Const *) other)->constvalue;
    1514        24226 :     consttype = ((Const *) other)->consttype;
    1515              : 
    1516              :     /*
    1517              :      * Force the var to be on the left to simplify logic in scalarineqsel.
    1518              :      */
    1519        24226 :     if (!varonleft)
    1520              :     {
    1521          192 :         operator = get_commutator(operator);
    1522          192 :         if (!operator)
    1523              :         {
    1524              :             /* Use default selectivity (should we raise an error instead?) */
    1525            0 :             ReleaseVariableStats(vardata);
    1526            0 :             PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    1527              :         }
    1528          192 :         isgt = !isgt;
    1529              :     }
    1530              : 
    1531              :     /* The rest of the work is done by scalarineqsel(). */
    1532        24226 :     selec = scalarineqsel(root, operator, isgt, iseq, collation,
    1533              :                           &vardata, constval, consttype);
    1534              : 
    1535        24226 :     ReleaseVariableStats(vardata);
    1536              : 
    1537        24226 :     PG_RETURN_FLOAT8((float8) selec);
    1538              : }
    1539              : 
    1540              : /*
    1541              :  *      scalarltsel     - Selectivity of "<" for scalars.
    1542              :  */
    1543              : Datum
    1544         7615 : scalarltsel(PG_FUNCTION_ARGS)
    1545              : {
    1546         7615 :     return scalarineqsel_wrapper(fcinfo, false, false);
    1547              : }
    1548              : 
    1549              : /*
    1550              :  *      scalarlesel     - Selectivity of "<=" for scalars.
    1551              :  */
    1552              : Datum
    1553         2318 : scalarlesel(PG_FUNCTION_ARGS)
    1554              : {
    1555         2318 :     return scalarineqsel_wrapper(fcinfo, false, true);
    1556              : }
    1557              : 
    1558              : /*
    1559              :  *      scalargtsel     - Selectivity of ">" for scalars.
    1560              :  */
    1561              : Datum
    1562         8130 : scalargtsel(PG_FUNCTION_ARGS)
    1563              : {
    1564         8130 :     return scalarineqsel_wrapper(fcinfo, true, false);
    1565              : }
    1566              : 
    1567              : /*
    1568              :  *      scalargesel     - Selectivity of ">=" for scalars.
    1569              :  */
    1570              : Datum
    1571         7939 : scalargesel(PG_FUNCTION_ARGS)
    1572              : {
    1573         7939 :     return scalarineqsel_wrapper(fcinfo, true, true);
    1574              : }
    1575              : 
    1576              : /*
    1577              :  *      boolvarsel      - Selectivity of Boolean variable.
    1578              :  *
    1579              :  * This can actually be called on any boolean-valued expression.  If it
    1580              :  * involves only Vars of the specified relation, and if there are statistics
    1581              :  * about the Var or expression (the latter is possible if it's indexed) then
    1582              :  * we'll produce a real estimate; otherwise it's just a default.
    1583              :  */
    1584              : Selectivity
    1585        35115 : boolvarsel(PlannerInfo *root, Node *arg, int varRelid)
    1586              : {
    1587              :     VariableStatData vardata;
    1588              :     double      selec;
    1589              : 
    1590        35115 :     examine_variable(root, arg, varRelid, &vardata);
    1591        35115 :     if (HeapTupleIsValid(vardata.statsTuple))
    1592              :     {
    1593              :         /*
    1594              :          * A boolean variable V is equivalent to the clause V = 't', so we
    1595              :          * compute the selectivity as if that is what we have.
    1596              :          */
    1597        19210 :         selec = var_eq_const(&vardata, BooleanEqualOperator, InvalidOid,
    1598              :                              BoolGetDatum(true), false, true, false);
    1599              :     }
    1600        15905 :     else if (is_funcclause(arg))
    1601              :     {
    1602              :         /*
    1603              :          * If we have no stats and it's a function call, estimate 0.3333333.
    1604              :          * This seems a pretty unprincipled choice, but Postgres has been
    1605              :          * using that estimate for function calls since 1992.  The hoariness
    1606              :          * of this behavior suggests that we should not be in too much hurry
    1607              :          * to use another value.
    1608              :          */
    1609         7041 :         selec = 0.3333333;
    1610              :     }
    1611              :     else
    1612              :     {
    1613              :         /* Otherwise, the default estimate is 0.5 */
    1614         8864 :         selec = 0.5;
    1615              :     }
    1616        35115 :     ReleaseVariableStats(vardata);
    1617        35115 :     return selec;
    1618              : }
    1619              : 
    1620              : /*
    1621              :  *      booltestsel     - Selectivity of BooleanTest Node.
    1622              :  */
    1623              : Selectivity
    1624          507 : booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg,
    1625              :             int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
    1626              : {
    1627              :     VariableStatData vardata;
    1628              :     double      selec;
    1629              : 
    1630          507 :     examine_variable(root, arg, varRelid, &vardata);
    1631              : 
    1632          507 :     if (HeapTupleIsValid(vardata.statsTuple))
    1633              :     {
    1634              :         Form_pg_statistic stats;
    1635              :         double      freq_null;
    1636              :         AttStatsSlot sslot;
    1637              : 
    1638           12 :         stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
    1639           12 :         freq_null = stats->stanullfrac;
    1640              : 
    1641           12 :         if (get_attstatsslot(&sslot, vardata.statsTuple,
    1642              :                              STATISTIC_KIND_MCV, InvalidOid,
    1643              :                              ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS)
    1644            6 :             && sslot.nnumbers > 0)
    1645            6 :         {
    1646              :             double      freq_true;
    1647              :             double      freq_false;
    1648              : 
    1649              :             /*
    1650              :              * Get first MCV frequency and derive frequency for true.
    1651              :              */
    1652            6 :             if (DatumGetBool(sslot.values[0]))
    1653            0 :                 freq_true = sslot.numbers[0];
    1654              :             else
    1655            6 :                 freq_true = 1.0 - sslot.numbers[0] - freq_null;
    1656              : 
    1657              :             /*
    1658              :              * Next derive frequency for false. Then use these as appropriate
    1659              :              * to derive frequency for each case.
    1660              :              */
    1661            6 :             freq_false = 1.0 - freq_true - freq_null;
    1662              : 
    1663            6 :             switch (booltesttype)
    1664              :             {
    1665            0 :                 case IS_UNKNOWN:
    1666              :                     /* select only NULL values */
    1667            0 :                     selec = freq_null;
    1668            0 :                     break;
    1669            0 :                 case IS_NOT_UNKNOWN:
    1670              :                     /* select non-NULL values */
    1671            0 :                     selec = 1.0 - freq_null;
    1672            0 :                     break;
    1673            6 :                 case IS_TRUE:
    1674              :                     /* select only TRUE values */
    1675            6 :                     selec = freq_true;
    1676            6 :                     break;
    1677            0 :                 case IS_NOT_TRUE:
    1678              :                     /* select non-TRUE values */
    1679            0 :                     selec = 1.0 - freq_true;
    1680            0 :                     break;
    1681            0 :                 case IS_FALSE:
    1682              :                     /* select only FALSE values */
    1683            0 :                     selec = freq_false;
    1684            0 :                     break;
    1685            0 :                 case IS_NOT_FALSE:
    1686              :                     /* select non-FALSE values */
    1687            0 :                     selec = 1.0 - freq_false;
    1688            0 :                     break;
    1689            0 :                 default:
    1690            0 :                     elog(ERROR, "unrecognized booltesttype: %d",
    1691              :                          (int) booltesttype);
    1692              :                     selec = 0.0;    /* Keep compiler quiet */
    1693              :                     break;
    1694              :             }
    1695              : 
    1696            6 :             free_attstatsslot(&sslot);
    1697              :         }
    1698              :         else
    1699              :         {
    1700              :             /*
    1701              :              * No most-common-value info available. Still have null fraction
    1702              :              * information, so use it for IS [NOT] UNKNOWN. Otherwise adjust
    1703              :              * for null fraction and assume a 50-50 split of TRUE and FALSE.
    1704              :              */
    1705            6 :             switch (booltesttype)
    1706              :             {
    1707            6 :                 case IS_UNKNOWN:
    1708              :                     /* select only NULL values */
    1709            6 :                     selec = freq_null;
    1710            6 :                     break;
    1711            0 :                 case IS_NOT_UNKNOWN:
    1712              :                     /* select non-NULL values */
    1713            0 :                     selec = 1.0 - freq_null;
    1714            0 :                     break;
    1715            0 :                 case IS_TRUE:
    1716              :                 case IS_FALSE:
    1717              :                     /* Assume we select half of the non-NULL values */
    1718            0 :                     selec = (1.0 - freq_null) / 2.0;
    1719            0 :                     break;
    1720            0 :                 case IS_NOT_TRUE:
    1721              :                 case IS_NOT_FALSE:
    1722              :                     /* Assume we select NULLs plus half of the non-NULLs */
    1723              :                     /* equiv. to freq_null + (1.0 - freq_null) / 2.0 */
    1724            0 :                     selec = (freq_null + 1.0) / 2.0;
    1725            0 :                     break;
    1726            0 :                 default:
    1727            0 :                     elog(ERROR, "unrecognized booltesttype: %d",
    1728              :                          (int) booltesttype);
    1729              :                     selec = 0.0;    /* Keep compiler quiet */
    1730              :                     break;
    1731              :             }
    1732              :         }
    1733              :     }
    1734              :     else
    1735              :     {
    1736              :         /*
    1737              :          * If we can't get variable statistics for the argument, perhaps
    1738              :          * clause_selectivity can do something with it.  We ignore the
    1739              :          * possibility of a NULL value when using clause_selectivity, and just
    1740              :          * assume the value is either TRUE or FALSE.
    1741              :          */
    1742          495 :         switch (booltesttype)
    1743              :         {
    1744           24 :             case IS_UNKNOWN:
    1745           24 :                 selec = DEFAULT_UNK_SEL;
    1746           24 :                 break;
    1747           54 :             case IS_NOT_UNKNOWN:
    1748           54 :                 selec = DEFAULT_NOT_UNK_SEL;
    1749           54 :                 break;
    1750          126 :             case IS_TRUE:
    1751              :             case IS_NOT_FALSE:
    1752          126 :                 selec = (double) clause_selectivity(root, arg,
    1753              :                                                     varRelid,
    1754              :                                                     jointype, sjinfo);
    1755          126 :                 break;
    1756          291 :             case IS_FALSE:
    1757              :             case IS_NOT_TRUE:
    1758          291 :                 selec = 1.0 - (double) clause_selectivity(root, arg,
    1759              :                                                           varRelid,
    1760              :                                                           jointype, sjinfo);
    1761          291 :                 break;
    1762            0 :             default:
    1763            0 :                 elog(ERROR, "unrecognized booltesttype: %d",
    1764              :                      (int) booltesttype);
    1765              :                 selec = 0.0;    /* Keep compiler quiet */
    1766              :                 break;
    1767              :         }
    1768              :     }
    1769              : 
    1770          507 :     ReleaseVariableStats(vardata);
    1771              : 
    1772              :     /* result should be in range, but make sure... */
    1773          507 :     CLAMP_PROBABILITY(selec);
    1774              : 
    1775          507 :     return (Selectivity) selec;
    1776              : }
    1777              : 
    1778              : /*
    1779              :  *      nulltestsel     - Selectivity of NullTest Node.
    1780              :  */
    1781              : Selectivity
    1782         9614 : nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg,
    1783              :             int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
    1784              : {
    1785              :     VariableStatData vardata;
    1786              :     double      selec;
    1787              : 
    1788         9614 :     examine_variable(root, arg, varRelid, &vardata);
    1789              : 
    1790         9614 :     if (HeapTupleIsValid(vardata.statsTuple))
    1791              :     {
    1792              :         Form_pg_statistic stats;
    1793              :         double      freq_null;
    1794              : 
    1795         5113 :         stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
    1796         5113 :         freq_null = stats->stanullfrac;
    1797              : 
    1798         5113 :         switch (nulltesttype)
    1799              :         {
    1800         3638 :             case IS_NULL:
    1801              : 
    1802              :                 /*
    1803              :                  * Use freq_null directly.
    1804              :                  */
    1805         3638 :                 selec = freq_null;
    1806         3638 :                 break;
    1807         1475 :             case IS_NOT_NULL:
    1808              : 
    1809              :                 /*
    1810              :                  * Select not unknown (not null) values. Calculate from
    1811              :                  * freq_null.
    1812              :                  */
    1813         1475 :                 selec = 1.0 - freq_null;
    1814         1475 :                 break;
    1815            0 :             default:
    1816            0 :                 elog(ERROR, "unrecognized nulltesttype: %d",
    1817              :                      (int) nulltesttype);
    1818              :                 return (Selectivity) 0; /* keep compiler quiet */
    1819              :         }
    1820              :     }
    1821         4501 :     else if (vardata.var && IsA(vardata.var, Var) &&
    1822         4109 :              ((Var *) vardata.var)->varattno < 0)
    1823              :     {
    1824              :         /*
    1825              :          * There are no stats for system columns, but we know they are never
    1826              :          * NULL.
    1827              :          */
    1828           52 :         selec = (nulltesttype == IS_NULL) ? 0.0 : 1.0;
    1829              :     }
    1830              :     else
    1831              :     {
    1832              :         /*
    1833              :          * No ANALYZE stats available, so make a guess
    1834              :          */
    1835         4449 :         switch (nulltesttype)
    1836              :         {
    1837         1108 :             case IS_NULL:
    1838         1108 :                 selec = DEFAULT_UNK_SEL;
    1839         1108 :                 break;
    1840         3341 :             case IS_NOT_NULL:
    1841         3341 :                 selec = DEFAULT_NOT_UNK_SEL;
    1842         3341 :                 break;
    1843            0 :             default:
    1844            0 :                 elog(ERROR, "unrecognized nulltesttype: %d",
    1845              :                      (int) nulltesttype);
    1846              :                 return (Selectivity) 0; /* keep compiler quiet */
    1847              :         }
    1848              :     }
    1849              : 
    1850         9614 :     ReleaseVariableStats(vardata);
    1851              : 
    1852              :     /* result should be in range, but make sure... */
    1853         9614 :     CLAMP_PROBABILITY(selec);
    1854              : 
    1855         9614 :     return (Selectivity) selec;
    1856              : }
    1857              : 
    1858              : /*
    1859              :  * strip_array_coercion - strip binary-compatible relabeling from an array expr
    1860              :  *
    1861              :  * For array values, the parser normally generates ArrayCoerceExpr conversions,
    1862              :  * but it seems possible that RelabelType might show up.  Also, the planner
    1863              :  * is not currently tense about collapsing stacked ArrayCoerceExpr nodes,
    1864              :  * so we need to be ready to deal with more than one level.
    1865              :  */
    1866              : static Node *
    1867        72792 : strip_array_coercion(Node *node)
    1868              : {
    1869              :     for (;;)
    1870              :     {
    1871        72848 :         if (node && IsA(node, ArrayCoerceExpr))
    1872           56 :         {
    1873         1749 :             ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
    1874              : 
    1875              :             /*
    1876              :              * If the per-element expression is just a RelabelType on top of
    1877              :              * CaseTestExpr, then we know it's a binary-compatible relabeling.
    1878              :              */
    1879         1749 :             if (IsA(acoerce->elemexpr, RelabelType) &&
    1880           56 :                 IsA(((RelabelType *) acoerce->elemexpr)->arg, CaseTestExpr))
    1881           56 :                 node = (Node *) acoerce->arg;
    1882              :             else
    1883              :                 break;
    1884              :         }
    1885        71099 :         else if (node && IsA(node, RelabelType))
    1886              :         {
    1887              :             /* We don't really expect this case, but may as well cope */
    1888            0 :             node = (Node *) ((RelabelType *) node)->arg;
    1889              :         }
    1890              :         else
    1891              :             break;
    1892              :     }
    1893        72792 :     return node;
    1894              : }
    1895              : 
    1896              : /*
    1897              :  *      scalararraysel      - Selectivity of ScalarArrayOpExpr Node.
    1898              :  */
    1899              : Selectivity
    1900        13216 : scalararraysel(PlannerInfo *root,
    1901              :                ScalarArrayOpExpr *clause,
    1902              :                bool is_join_clause,
    1903              :                int varRelid,
    1904              :                JoinType jointype,
    1905              :                SpecialJoinInfo *sjinfo)
    1906              : {
    1907        13216 :     Oid         operator = clause->opno;
    1908        13216 :     bool        useOr = clause->useOr;
    1909        13216 :     bool        isEquality = false;
    1910        13216 :     bool        isInequality = false;
    1911              :     Node       *leftop;
    1912              :     Node       *rightop;
    1913              :     Oid         nominal_element_type;
    1914              :     Oid         nominal_element_collation;
    1915              :     TypeCacheEntry *typentry;
    1916              :     RegProcedure oprsel;
    1917              :     FmgrInfo    oprselproc;
    1918              :     Selectivity s1;
    1919              :     Selectivity s1disjoint;
    1920              : 
    1921              :     /* First, deconstruct the expression */
    1922              :     Assert(list_length(clause->args) == 2);
    1923        13216 :     leftop = (Node *) linitial(clause->args);
    1924        13216 :     rightop = (Node *) lsecond(clause->args);
    1925              : 
    1926              :     /* aggressively reduce both sides to constants */
    1927        13216 :     leftop = estimate_expression_value(root, leftop);
    1928        13216 :     rightop = estimate_expression_value(root, rightop);
    1929              : 
    1930              :     /* get nominal (after relabeling) element type of rightop */
    1931        13216 :     nominal_element_type = get_base_element_type(exprType(rightop));
    1932        13216 :     if (!OidIsValid(nominal_element_type))
    1933            0 :         return (Selectivity) 0.5;   /* probably shouldn't happen */
    1934              :     /* get nominal collation, too, for generating constants */
    1935        13216 :     nominal_element_collation = exprCollation(rightop);
    1936              : 
    1937              :     /* look through any binary-compatible relabeling of rightop */
    1938        13216 :     rightop = strip_array_coercion(rightop);
    1939              : 
    1940              :     /*
    1941              :      * Detect whether the operator is the default equality or inequality
    1942              :      * operator of the array element type.
    1943              :      */
    1944        13216 :     typentry = lookup_type_cache(nominal_element_type, TYPECACHE_EQ_OPR);
    1945        13216 :     if (OidIsValid(typentry->eq_opr))
    1946              :     {
    1947        13214 :         if (operator == typentry->eq_opr)
    1948        11428 :             isEquality = true;
    1949         1786 :         else if (get_negator(operator) == typentry->eq_opr)
    1950         1503 :             isInequality = true;
    1951              :     }
    1952              : 
    1953              :     /*
    1954              :      * If it is equality or inequality, we might be able to estimate this as a
    1955              :      * form of array containment; for instance "const = ANY(column)" can be
    1956              :      * treated as "ARRAY[const] <@ column".  scalararraysel_containment tries
    1957              :      * that, and returns the selectivity estimate if successful, or -1 if not.
    1958              :      */
    1959        13216 :     if ((isEquality || isInequality) && !is_join_clause)
    1960              :     {
    1961        12930 :         s1 = scalararraysel_containment(root, leftop, rightop,
    1962              :                                         nominal_element_type,
    1963              :                                         isEquality, useOr, varRelid);
    1964        12930 :         if (s1 >= 0.0)
    1965           59 :             return s1;
    1966              :     }
    1967              : 
    1968              :     /*
    1969              :      * Look up the underlying operator's selectivity estimator. Punt if it
    1970              :      * hasn't got one.
    1971              :      */
    1972        13157 :     if (is_join_clause)
    1973            1 :         oprsel = get_oprjoin(operator);
    1974              :     else
    1975        13156 :         oprsel = get_oprrest(operator);
    1976        13157 :     if (!oprsel)
    1977            2 :         return (Selectivity) 0.5;
    1978        13155 :     fmgr_info(oprsel, &oprselproc);
    1979              : 
    1980              :     /*
    1981              :      * In the array-containment check above, we must only believe that an
    1982              :      * operator is equality or inequality if it is the default btree equality
    1983              :      * operator (or its negator) for the element type, since those are the
    1984              :      * operators that array containment will use.  But in what follows, we can
    1985              :      * be a little laxer, and also believe that any operators using eqsel() or
    1986              :      * neqsel() as selectivity estimator act like equality or inequality.
    1987              :      */
    1988        13155 :     if (oprsel == F_EQSEL || oprsel == F_EQJOINSEL)
    1989        11467 :         isEquality = true;
    1990         1688 :     else if (oprsel == F_NEQSEL || oprsel == F_NEQJOINSEL)
    1991         1448 :         isInequality = true;
    1992              : 
    1993              :     /*
    1994              :      * We consider three cases:
    1995              :      *
    1996              :      * 1. rightop is an Array constant: deconstruct the array, apply the
    1997              :      * operator's selectivity function for each array element, and merge the
    1998              :      * results in the same way that clausesel.c does for AND/OR combinations.
    1999              :      *
    2000              :      * 2. rightop is an ARRAY[] construct: apply the operator's selectivity
    2001              :      * function for each element of the ARRAY[] construct, and merge.
    2002              :      *
    2003              :      * 3. otherwise, make a guess ...
    2004              :      */
    2005        13155 :     if (rightop && IsA(rightop, Const))
    2006        10831 :     {
    2007        10846 :         Datum       arraydatum = ((Const *) rightop)->constvalue;
    2008        10846 :         bool        arrayisnull = ((Const *) rightop)->constisnull;
    2009              :         ArrayType  *arrayval;
    2010              :         int16       elmlen;
    2011              :         bool        elmbyval;
    2012              :         char        elmalign;
    2013              :         int         num_elems;
    2014              :         Datum      *elem_values;
    2015              :         bool       *elem_nulls;
    2016              :         int         i;
    2017              : 
    2018        10846 :         if (arrayisnull)        /* qual can't succeed if null array */
    2019           15 :             return (Selectivity) 0.0;
    2020        10831 :         arrayval = DatumGetArrayTypeP(arraydatum);
    2021        10831 :         get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
    2022              :                              &elmlen, &elmbyval, &elmalign);
    2023        10831 :         deconstruct_array(arrayval,
    2024              :                           ARR_ELEMTYPE(arrayval),
    2025              :                           elmlen, elmbyval, elmalign,
    2026              :                           &elem_values, &elem_nulls, &num_elems);
    2027              : 
    2028              :         /*
    2029              :          * For generic operators, we assume the probability of success is
    2030              :          * independent for each array element.  But for "= ANY" or "<> ALL",
    2031              :          * if the array elements are distinct (which'd typically be the case)
    2032              :          * then the probabilities are disjoint, and we should just sum them.
    2033              :          *
    2034              :          * If we were being really tense we would try to confirm that the
    2035              :          * elements are all distinct, but that would be expensive and it
    2036              :          * doesn't seem to be worth the cycles; it would amount to penalizing
    2037              :          * well-written queries in favor of poorly-written ones.  However, we
    2038              :          * do protect ourselves a little bit by checking whether the
    2039              :          * disjointness assumption leads to an impossible (out of range)
    2040              :          * probability; if so, we fall back to the normal calculation.
    2041              :          */
    2042        10831 :         s1 = s1disjoint = (useOr ? 0.0 : 1.0);
    2043              : 
    2044        44733 :         for (i = 0; i < num_elems; i++)
    2045              :         {
    2046              :             List       *args;
    2047              :             Selectivity s2;
    2048              : 
    2049        33902 :             args = list_make2(leftop,
    2050              :                               makeConst(nominal_element_type,
    2051              :                                         -1,
    2052              :                                         nominal_element_collation,
    2053              :                                         elmlen,
    2054              :                                         elem_values[i],
    2055              :                                         elem_nulls[i],
    2056              :                                         elmbyval));
    2057        33902 :             if (is_join_clause)
    2058            0 :                 s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc,
    2059              :                                                       clause->inputcollid,
    2060              :                                                       PointerGetDatum(root),
    2061              :                                                       ObjectIdGetDatum(operator),
    2062              :                                                       PointerGetDatum(args),
    2063              :                                                       Int16GetDatum(jointype),
    2064              :                                                       PointerGetDatum(sjinfo)));
    2065              :             else
    2066        33902 :                 s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc,
    2067              :                                                       clause->inputcollid,
    2068              :                                                       PointerGetDatum(root),
    2069              :                                                       ObjectIdGetDatum(operator),
    2070              :                                                       PointerGetDatum(args),
    2071              :                                                       Int32GetDatum(varRelid)));
    2072              : 
    2073        33902 :             if (useOr)
    2074              :             {
    2075        29215 :                 s1 = s1 + s2 - s1 * s2;
    2076        29215 :                 if (isEquality)
    2077        28693 :                     s1disjoint += s2;
    2078              :             }
    2079              :             else
    2080              :             {
    2081         4687 :                 s1 = s1 * s2;
    2082         4687 :                 if (isInequality)
    2083         4531 :                     s1disjoint += s2 - 1.0;
    2084              :             }
    2085              :         }
    2086              : 
    2087              :         /* accept disjoint-probability estimate if in range */
    2088        10831 :         if ((useOr ? isEquality : isInequality) &&
    2089        10519 :             s1disjoint >= 0.0 && s1disjoint <= 1.0)
    2090        10495 :             s1 = s1disjoint;
    2091              :     }
    2092         2309 :     else if (rightop && IsA(rightop, ArrayExpr) &&
    2093          193 :              !((ArrayExpr *) rightop)->multidims)
    2094          193 :     {
    2095          193 :         ArrayExpr  *arrayexpr = (ArrayExpr *) rightop;
    2096              :         int16       elmlen;
    2097              :         bool        elmbyval;
    2098              :         ListCell   *l;
    2099              : 
    2100          193 :         get_typlenbyval(arrayexpr->element_typeid,
    2101              :                         &elmlen, &elmbyval);
    2102              : 
    2103              :         /*
    2104              :          * We use the assumption of disjoint probabilities here too, although
    2105              :          * the odds of equal array elements are rather higher if the elements
    2106              :          * are not all constants (which they won't be, else constant folding
    2107              :          * would have reduced the ArrayExpr to a Const).  In this path it's
    2108              :          * critical to have the sanity check on the s1disjoint estimate.
    2109              :          */
    2110          193 :         s1 = s1disjoint = (useOr ? 0.0 : 1.0);
    2111              : 
    2112          714 :         foreach(l, arrayexpr->elements)
    2113              :         {
    2114          521 :             Node       *elem = (Node *) lfirst(l);
    2115              :             List       *args;
    2116              :             Selectivity s2;
    2117              : 
    2118              :             /*
    2119              :              * Theoretically, if elem isn't of nominal_element_type we should
    2120              :              * insert a RelabelType, but it seems unlikely that any operator
    2121              :              * estimation function would really care ...
    2122              :              */
    2123          521 :             args = list_make2(leftop, elem);
    2124          521 :             if (is_join_clause)
    2125            3 :                 s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc,
    2126              :                                                       clause->inputcollid,
    2127              :                                                       PointerGetDatum(root),
    2128              :                                                       ObjectIdGetDatum(operator),
    2129              :                                                       PointerGetDatum(args),
    2130              :                                                       Int16GetDatum(jointype),
    2131              :                                                       PointerGetDatum(sjinfo)));
    2132              :             else
    2133          518 :                 s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc,
    2134              :                                                       clause->inputcollid,
    2135              :                                                       PointerGetDatum(root),
    2136              :                                                       ObjectIdGetDatum(operator),
    2137              :                                                       PointerGetDatum(args),
    2138              :                                                       Int32GetDatum(varRelid)));
    2139              : 
    2140          521 :             if (useOr)
    2141              :             {
    2142          521 :                 s1 = s1 + s2 - s1 * s2;
    2143          521 :                 if (isEquality)
    2144          521 :                     s1disjoint += s2;
    2145              :             }
    2146              :             else
    2147              :             {
    2148            0 :                 s1 = s1 * s2;
    2149            0 :                 if (isInequality)
    2150            0 :                     s1disjoint += s2 - 1.0;
    2151              :             }
    2152              :         }
    2153              : 
    2154              :         /* accept disjoint-probability estimate if in range */
    2155          193 :         if ((useOr ? isEquality : isInequality) &&
    2156          193 :             s1disjoint >= 0.0 && s1disjoint <= 1.0)
    2157          193 :             s1 = s1disjoint;
    2158              :     }
    2159              :     else
    2160              :     {
    2161              :         CaseTestExpr *dummyexpr;
    2162              :         List       *args;
    2163              :         Selectivity s2;
    2164              :         int         i;
    2165              : 
    2166              :         /*
    2167              :          * We need a dummy rightop to pass to the operator selectivity
    2168              :          * routine.  It can be pretty much anything that doesn't look like a
    2169              :          * constant; CaseTestExpr is a convenient choice.
    2170              :          */
    2171         2116 :         dummyexpr = makeNode(CaseTestExpr);
    2172         2116 :         dummyexpr->typeId = nominal_element_type;
    2173         2116 :         dummyexpr->typeMod = -1;
    2174         2116 :         dummyexpr->collation = clause->inputcollid;
    2175         2116 :         args = list_make2(leftop, dummyexpr);
    2176         2116 :         if (is_join_clause)
    2177            0 :             s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc,
    2178              :                                                   clause->inputcollid,
    2179              :                                                   PointerGetDatum(root),
    2180              :                                                   ObjectIdGetDatum(operator),
    2181              :                                                   PointerGetDatum(args),
    2182              :                                                   Int16GetDatum(jointype),
    2183              :                                                   PointerGetDatum(sjinfo)));
    2184              :         else
    2185         2116 :             s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc,
    2186              :                                                   clause->inputcollid,
    2187              :                                                   PointerGetDatum(root),
    2188              :                                                   ObjectIdGetDatum(operator),
    2189              :                                                   PointerGetDatum(args),
    2190              :                                                   Int32GetDatum(varRelid)));
    2191         2116 :         s1 = useOr ? 0.0 : 1.0;
    2192              : 
    2193              :         /*
    2194              :          * Arbitrarily assume 10 elements in the eventual array value (see
    2195              :          * also estimate_array_length).  We don't risk an assumption of
    2196              :          * disjoint probabilities here.
    2197              :          */
    2198        23276 :         for (i = 0; i < 10; i++)
    2199              :         {
    2200        21160 :             if (useOr)
    2201        21160 :                 s1 = s1 + s2 - s1 * s2;
    2202              :             else
    2203            0 :                 s1 = s1 * s2;
    2204              :         }
    2205              :     }
    2206              : 
    2207              :     /* result should be in range, but make sure... */
    2208        13140 :     CLAMP_PROBABILITY(s1);
    2209              : 
    2210        13140 :     return s1;
    2211              : }
    2212              : 
    2213              : /*
    2214              :  * Estimate number of elements in the array yielded by an expression.
    2215              :  *
    2216              :  * Note: the result is integral, but we use "double" to avoid overflow
    2217              :  * concerns.  Most callers will use it in double-type expressions anyway.
    2218              :  *
    2219              :  * Note: in some code paths root can be passed as NULL, resulting in
    2220              :  * slightly worse estimates.
    2221              :  */
    2222              : double
    2223        59576 : estimate_array_length(PlannerInfo *root, Node *arrayexpr)
    2224              : {
    2225              :     /* look through any binary-compatible relabeling of arrayexpr */
    2226        59576 :     arrayexpr = strip_array_coercion(arrayexpr);
    2227              : 
    2228        59576 :     if (arrayexpr && IsA(arrayexpr, Const))
    2229              :     {
    2230        28041 :         Datum       arraydatum = ((Const *) arrayexpr)->constvalue;
    2231        28041 :         bool        arrayisnull = ((Const *) arrayexpr)->constisnull;
    2232              :         ArrayType  *arrayval;
    2233              : 
    2234        28041 :         if (arrayisnull)
    2235           45 :             return 0;
    2236        27996 :         arrayval = DatumGetArrayTypeP(arraydatum);
    2237        27996 :         return ArrayGetNItems(ARR_NDIM(arrayval), ARR_DIMS(arrayval));
    2238              :     }
    2239        31535 :     else if (arrayexpr && IsA(arrayexpr, ArrayExpr) &&
    2240          342 :              !((ArrayExpr *) arrayexpr)->multidims)
    2241              :     {
    2242          342 :         return list_length(((ArrayExpr *) arrayexpr)->elements);
    2243              :     }
    2244        31193 :     else if (arrayexpr && root)
    2245              :     {
    2246              :         /* See if we can find any statistics about it */
    2247              :         VariableStatData vardata;
    2248              :         AttStatsSlot sslot;
    2249        31181 :         double      nelem = 0;
    2250              : 
    2251        31181 :         examine_variable(root, arrayexpr, 0, &vardata);
    2252        31181 :         if (HeapTupleIsValid(vardata.statsTuple))
    2253              :         {
    2254              :             /*
    2255              :              * Found stats, so use the average element count, which is stored
    2256              :              * in the last stanumbers element of the DECHIST statistics.
    2257              :              * Actually that is the average count of *distinct* elements;
    2258              :              * perhaps we should scale it up somewhat?
    2259              :              */
    2260         4945 :             if (get_attstatsslot(&sslot, vardata.statsTuple,
    2261              :                                  STATISTIC_KIND_DECHIST, InvalidOid,
    2262              :                                  ATTSTATSSLOT_NUMBERS))
    2263              :             {
    2264         4888 :                 if (sslot.nnumbers > 0)
    2265         4888 :                     nelem = clamp_row_est(sslot.numbers[sslot.nnumbers - 1]);
    2266         4888 :                 free_attstatsslot(&sslot);
    2267              :             }
    2268              :         }
    2269        31181 :         ReleaseVariableStats(vardata);
    2270              : 
    2271        31181 :         if (nelem > 0)
    2272         4888 :             return nelem;
    2273              :     }
    2274              : 
    2275              :     /* Else use a default guess --- this should match scalararraysel */
    2276        26305 :     return 10;
    2277              : }
    2278              : 
    2279              : /*
    2280              :  *      rowcomparesel       - Selectivity of RowCompareExpr Node.
    2281              :  *
    2282              :  * We estimate RowCompare selectivity by considering just the first (high
    2283              :  * order) columns, which makes it equivalent to an ordinary OpExpr.  While
    2284              :  * this estimate could be refined by considering additional columns, it
    2285              :  * seems unlikely that we could do a lot better without multi-column
    2286              :  * statistics.
    2287              :  */
    2288              : Selectivity
    2289          126 : rowcomparesel(PlannerInfo *root,
    2290              :               RowCompareExpr *clause,
    2291              :               int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
    2292              : {
    2293              :     Selectivity s1;
    2294          126 :     Oid         opno = linitial_oid(clause->opnos);
    2295          126 :     Oid         inputcollid = linitial_oid(clause->inputcollids);
    2296              :     List       *opargs;
    2297              :     bool        is_join_clause;
    2298              : 
    2299              :     /* Build equivalent arg list for single operator */
    2300          126 :     opargs = list_make2(linitial(clause->largs), linitial(clause->rargs));
    2301              : 
    2302              :     /*
    2303              :      * Decide if it's a join clause.  This should match clausesel.c's
    2304              :      * treat_as_join_clause(), except that we intentionally consider only the
    2305              :      * leading columns and not the rest of the clause.
    2306              :      */
    2307          126 :     if (varRelid != 0)
    2308              :     {
    2309              :         /*
    2310              :          * Caller is forcing restriction mode (eg, because we are examining an
    2311              :          * inner indexscan qual).
    2312              :          */
    2313           27 :         is_join_clause = false;
    2314              :     }
    2315           99 :     else if (sjinfo == NULL)
    2316              :     {
    2317              :         /*
    2318              :          * It must be a restriction clause, since it's being evaluated at a
    2319              :          * scan node.
    2320              :          */
    2321           93 :         is_join_clause = false;
    2322              :     }
    2323              :     else
    2324              :     {
    2325              :         /*
    2326              :          * Otherwise, it's a join if there's more than one base relation used.
    2327              :          */
    2328            6 :         is_join_clause = (NumRelids(root, (Node *) opargs) > 1);
    2329              :     }
    2330              : 
    2331          126 :     if (is_join_clause)
    2332              :     {
    2333              :         /* Estimate selectivity for a join clause. */
    2334            6 :         s1 = join_selectivity(root, opno,
    2335              :                               opargs,
    2336              :                               inputcollid,
    2337              :                               jointype,
    2338              :                               sjinfo);
    2339              :     }
    2340              :     else
    2341              :     {
    2342              :         /* Estimate selectivity for a restriction clause. */
    2343          120 :         s1 = restriction_selectivity(root, opno,
    2344              :                                      opargs,
    2345              :                                      inputcollid,
    2346              :                                      varRelid);
    2347              :     }
    2348              : 
    2349          126 :     return s1;
    2350              : }
    2351              : 
    2352              : /*
    2353              :  *      eqjoinsel       - Join selectivity of "="
    2354              :  */
    2355              : Datum
    2356       154326 : eqjoinsel(PG_FUNCTION_ARGS)
    2357              : {
    2358       154326 :     PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
    2359       154326 :     Oid         operator = PG_GETARG_OID(1);
    2360       154326 :     List       *args = (List *) PG_GETARG_POINTER(2);
    2361              : 
    2362              : #ifdef NOT_USED
    2363              :     JoinType    jointype = (JoinType) PG_GETARG_INT16(3);
    2364              : #endif
    2365       154326 :     SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) PG_GETARG_POINTER(4);
    2366       154326 :     Oid         collation = PG_GET_COLLATION();
    2367              :     double      selec;
    2368              :     double      selec_inner;
    2369              :     VariableStatData vardata1;
    2370              :     VariableStatData vardata2;
    2371              :     double      nd1;
    2372              :     double      nd2;
    2373              :     bool        isdefault1;
    2374              :     bool        isdefault2;
    2375              :     Oid         opfuncoid;
    2376              :     FmgrInfo    eqproc;
    2377       154326 :     Oid         hashLeft = InvalidOid;
    2378       154326 :     Oid         hashRight = InvalidOid;
    2379              :     AttStatsSlot sslot1;
    2380              :     AttStatsSlot sslot2;
    2381       154326 :     Form_pg_statistic stats1 = NULL;
    2382       154326 :     Form_pg_statistic stats2 = NULL;
    2383       154326 :     bool        have_mcvs1 = false;
    2384       154326 :     bool        have_mcvs2 = false;
    2385       154326 :     bool       *hasmatch1 = NULL;
    2386       154326 :     bool       *hasmatch2 = NULL;
    2387       154326 :     int         nmatches = 0;
    2388              :     bool        get_mcv_stats;
    2389              :     bool        join_is_reversed;
    2390              :     RelOptInfo *inner_rel;
    2391              : 
    2392       154326 :     get_join_variables(root, args, sjinfo,
    2393              :                        &vardata1, &vardata2, &join_is_reversed);
    2394              : 
    2395       154326 :     nd1 = get_variable_numdistinct(&vardata1, &isdefault1);
    2396       154326 :     nd2 = get_variable_numdistinct(&vardata2, &isdefault2);
    2397              : 
    2398       154326 :     opfuncoid = get_opcode(operator);
    2399              : 
    2400       154326 :     memset(&sslot1, 0, sizeof(sslot1));
    2401       154326 :     memset(&sslot2, 0, sizeof(sslot2));
    2402              : 
    2403              :     /*
    2404              :      * There is no use in fetching one side's MCVs if we lack MCVs for the
    2405              :      * other side, so do a quick check to verify that both stats exist.
    2406              :      */
    2407       416766 :     get_mcv_stats = (HeapTupleIsValid(vardata1.statsTuple) &&
    2408       191494 :                      HeapTupleIsValid(vardata2.statsTuple) &&
    2409        83380 :                      get_attstatsslot(&sslot1, vardata1.statsTuple,
    2410              :                                       STATISTIC_KIND_MCV, InvalidOid,
    2411       262440 :                                       0) &&
    2412        39815 :                      get_attstatsslot(&sslot2, vardata2.statsTuple,
    2413              :                                       STATISTIC_KIND_MCV, InvalidOid,
    2414              :                                       0));
    2415              : 
    2416       154326 :     if (HeapTupleIsValid(vardata1.statsTuple))
    2417              :     {
    2418              :         /* note we allow use of nullfrac regardless of security check */
    2419       108114 :         stats1 = (Form_pg_statistic) GETSTRUCT(vardata1.statsTuple);
    2420       123146 :         if (get_mcv_stats &&
    2421        15032 :             statistic_proc_security_check(&vardata1, opfuncoid))
    2422        15032 :             have_mcvs1 = get_attstatsslot(&sslot1, vardata1.statsTuple,
    2423              :                                           STATISTIC_KIND_MCV, InvalidOid,
    2424              :                                           ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
    2425              :     }
    2426              : 
    2427       154326 :     if (HeapTupleIsValid(vardata2.statsTuple))
    2428              :     {
    2429              :         /* note we allow use of nullfrac regardless of security check */
    2430        97407 :         stats2 = (Form_pg_statistic) GETSTRUCT(vardata2.statsTuple);
    2431       112439 :         if (get_mcv_stats &&
    2432        15032 :             statistic_proc_security_check(&vardata2, opfuncoid))
    2433        15032 :             have_mcvs2 = get_attstatsslot(&sslot2, vardata2.statsTuple,
    2434              :                                           STATISTIC_KIND_MCV, InvalidOid,
    2435              :                                           ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
    2436              :     }
    2437              : 
    2438              :     /* Prepare info usable by both eqjoinsel_inner and eqjoinsel_semi */
    2439       154326 :     if (have_mcvs1 && have_mcvs2)
    2440              :     {
    2441        15032 :         fmgr_info(opfuncoid, &eqproc);
    2442        15032 :         hasmatch1 = (bool *) palloc0(sslot1.nvalues * sizeof(bool));
    2443        15032 :         hasmatch2 = (bool *) palloc0(sslot2.nvalues * sizeof(bool));
    2444              : 
    2445              :         /*
    2446              :          * If the MCV lists are long enough to justify hashing, try to look up
    2447              :          * hash functions for the join operator.
    2448              :          */
    2449        15032 :         if ((sslot1.nvalues + sslot2.nvalues) >= EQJOINSEL_MCV_HASH_THRESHOLD)
    2450          967 :             (void) get_op_hash_functions(operator, &hashLeft, &hashRight);
    2451              :     }
    2452              :     else
    2453       139294 :         memset(&eqproc, 0, sizeof(eqproc)); /* silence uninit-var warnings */
    2454              : 
    2455              :     /* We need to compute the inner-join selectivity in all cases */
    2456       154326 :     selec_inner = eqjoinsel_inner(&eqproc, collation,
    2457              :                                   hashLeft, hashRight,
    2458              :                                   &vardata1, &vardata2,
    2459              :                                   nd1, nd2,
    2460              :                                   isdefault1, isdefault2,
    2461              :                                   &sslot1, &sslot2,
    2462              :                                   stats1, stats2,
    2463              :                                   have_mcvs1, have_mcvs2,
    2464              :                                   hasmatch1, hasmatch2,
    2465              :                                   &nmatches);
    2466              : 
    2467       154326 :     switch (sjinfo->jointype)
    2468              :     {
    2469       147076 :         case JOIN_INNER:
    2470              :         case JOIN_LEFT:
    2471              :         case JOIN_FULL:
    2472       147076 :             selec = selec_inner;
    2473       147076 :             break;
    2474         7250 :         case JOIN_SEMI:
    2475              :         case JOIN_ANTI:
    2476              : 
    2477              :             /*
    2478              :              * Look up the join's inner relation.  min_righthand is sufficient
    2479              :              * information because neither SEMI nor ANTI joins permit any
    2480              :              * reassociation into or out of their RHS, so the righthand will
    2481              :              * always be exactly that set of rels.
    2482              :              */
    2483         7250 :             inner_rel = find_join_input_rel(root, sjinfo->min_righthand);
    2484              : 
    2485         7250 :             if (!join_is_reversed)
    2486         3528 :                 selec = eqjoinsel_semi(&eqproc, collation,
    2487              :                                        hashLeft, hashRight,
    2488              :                                        false,
    2489              :                                        &vardata1, &vardata2,
    2490              :                                        nd1, nd2,
    2491              :                                        isdefault1, isdefault2,
    2492              :                                        &sslot1, &sslot2,
    2493              :                                        stats1, stats2,
    2494              :                                        have_mcvs1, have_mcvs2,
    2495              :                                        hasmatch1, hasmatch2,
    2496              :                                        &nmatches,
    2497              :                                        inner_rel);
    2498              :             else
    2499         3722 :                 selec = eqjoinsel_semi(&eqproc, collation,
    2500              :                                        hashLeft, hashRight,
    2501              :                                        true,
    2502              :                                        &vardata2, &vardata1,
    2503              :                                        nd2, nd1,
    2504              :                                        isdefault2, isdefault1,
    2505              :                                        &sslot2, &sslot1,
    2506              :                                        stats2, stats1,
    2507              :                                        have_mcvs2, have_mcvs1,
    2508              :                                        hasmatch2, hasmatch1,
    2509              :                                        &nmatches,
    2510              :                                        inner_rel);
    2511              : 
    2512              :             /*
    2513              :              * We should never estimate the output of a semijoin to be more
    2514              :              * rows than we estimate for an inner join with the same input
    2515              :              * rels and join condition; it's obviously impossible for that to
    2516              :              * happen.  The former estimate is N1 * Ssemi while the latter is
    2517              :              * N1 * N2 * Sinner, so we may clamp Ssemi <= N2 * Sinner.  Doing
    2518              :              * this is worthwhile because of the shakier estimation rules we
    2519              :              * use in eqjoinsel_semi, particularly in cases where it has to
    2520              :              * punt entirely.
    2521              :              */
    2522         7250 :             selec = Min(selec, inner_rel->rows * selec_inner);
    2523         7250 :             break;
    2524            0 :         default:
    2525              :             /* other values not expected here */
    2526            0 :             elog(ERROR, "unrecognized join type: %d",
    2527              :                  (int) sjinfo->jointype);
    2528              :             selec = 0;          /* keep compiler quiet */
    2529              :             break;
    2530              :     }
    2531              : 
    2532       154326 :     free_attstatsslot(&sslot1);
    2533       154326 :     free_attstatsslot(&sslot2);
    2534              : 
    2535       154326 :     ReleaseVariableStats(vardata1);
    2536       154326 :     ReleaseVariableStats(vardata2);
    2537              : 
    2538       154326 :     if (hasmatch1)
    2539        15032 :         pfree(hasmatch1);
    2540       154326 :     if (hasmatch2)
    2541        15032 :         pfree(hasmatch2);
    2542              : 
    2543       154326 :     CLAMP_PROBABILITY(selec);
    2544              : 
    2545       154326 :     PG_RETURN_FLOAT8((float8) selec);
    2546              : }
    2547              : 
    2548              : /*
    2549              :  * eqjoinsel_inner --- eqjoinsel for normal inner join
    2550              :  *
    2551              :  * In addition to computing the selectivity estimate, this will fill
    2552              :  * hasmatch1[], hasmatch2[], and *p_nmatches (if have_mcvs1 && have_mcvs2).
    2553              :  * We may be able to re-use that data in eqjoinsel_semi.
    2554              :  *
    2555              :  * We also use this for LEFT/FULL outer joins; it's not presently clear
    2556              :  * that it's worth trying to distinguish them here.
    2557              :  */
    2558              : static double
    2559       154326 : eqjoinsel_inner(FmgrInfo *eqproc, Oid collation,
    2560              :                 Oid hashLeft, Oid hashRight,
    2561              :                 VariableStatData *vardata1, VariableStatData *vardata2,
    2562              :                 double nd1, double nd2,
    2563              :                 bool isdefault1, bool isdefault2,
    2564              :                 AttStatsSlot *sslot1, AttStatsSlot *sslot2,
    2565              :                 Form_pg_statistic stats1, Form_pg_statistic stats2,
    2566              :                 bool have_mcvs1, bool have_mcvs2,
    2567              :                 bool *hasmatch1, bool *hasmatch2,
    2568              :                 int *p_nmatches)
    2569              : {
    2570              :     double      selec;
    2571              : 
    2572       154326 :     if (have_mcvs1 && have_mcvs2)
    2573        15032 :     {
    2574              :         /*
    2575              :          * We have most-common-value lists for both relations.  Run through
    2576              :          * the lists to see which MCVs actually join to each other with the
    2577              :          * given operator.  This allows us to determine the exact join
    2578              :          * selectivity for the portion of the relations represented by the MCV
    2579              :          * lists.  We still have to estimate for the remaining population, but
    2580              :          * in a skewed distribution this gives us a big leg up in accuracy.
    2581              :          * For motivation see the analysis in Y. Ioannidis and S.
    2582              :          * Christodoulakis, "On the propagation of errors in the size of join
    2583              :          * results", Technical Report 1018, Computer Science Dept., University
    2584              :          * of Wisconsin, Madison, March 1991 (available from ftp.cs.wisc.edu).
    2585              :          */
    2586        15032 :         double      nullfrac1 = stats1->stanullfrac;
    2587        15032 :         double      nullfrac2 = stats2->stanullfrac;
    2588              :         double      matchprodfreq,
    2589              :                     matchfreq1,
    2590              :                     matchfreq2,
    2591              :                     unmatchfreq1,
    2592              :                     unmatchfreq2,
    2593              :                     otherfreq1,
    2594              :                     otherfreq2,
    2595              :                     totalsel1,
    2596              :                     totalsel2;
    2597              :         int         i,
    2598              :                     nmatches;
    2599              : 
    2600              :         /* Fill the match arrays */
    2601        15032 :         eqjoinsel_find_matches(eqproc, collation,
    2602              :                                hashLeft, hashRight,
    2603              :                                false,
    2604              :                                sslot1, sslot2,
    2605              :                                sslot1->nvalues, sslot2->nvalues,
    2606              :                                hasmatch1, hasmatch2,
    2607              :                                p_nmatches, &matchprodfreq);
    2608        15032 :         nmatches = *p_nmatches;
    2609        15032 :         CLAMP_PROBABILITY(matchprodfreq);
    2610              : 
    2611              :         /* Sum up frequencies of matched and unmatched MCVs */
    2612        15032 :         matchfreq1 = unmatchfreq1 = 0.0;
    2613       423931 :         for (i = 0; i < sslot1->nvalues; i++)
    2614              :         {
    2615       408899 :             if (hasmatch1[i])
    2616       163120 :                 matchfreq1 += sslot1->numbers[i];
    2617              :             else
    2618       245779 :                 unmatchfreq1 += sslot1->numbers[i];
    2619              :         }
    2620        15032 :         CLAMP_PROBABILITY(matchfreq1);
    2621        15032 :         CLAMP_PROBABILITY(unmatchfreq1);
    2622        15032 :         matchfreq2 = unmatchfreq2 = 0.0;
    2623       302839 :         for (i = 0; i < sslot2->nvalues; i++)
    2624              :         {
    2625       287807 :             if (hasmatch2[i])
    2626       163120 :                 matchfreq2 += sslot2->numbers[i];
    2627              :             else
    2628       124687 :                 unmatchfreq2 += sslot2->numbers[i];
    2629              :         }
    2630        15032 :         CLAMP_PROBABILITY(matchfreq2);
    2631        15032 :         CLAMP_PROBABILITY(unmatchfreq2);
    2632              : 
    2633              :         /*
    2634              :          * Compute total frequency of non-null values that are not in the MCV
    2635              :          * lists.
    2636              :          */
    2637        15032 :         otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
    2638        15032 :         otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
    2639        15032 :         CLAMP_PROBABILITY(otherfreq1);
    2640        15032 :         CLAMP_PROBABILITY(otherfreq2);
    2641              : 
    2642              :         /*
    2643              :          * We can estimate the total selectivity from the point of view of
    2644              :          * relation 1 as: the known selectivity for matched MCVs, plus
    2645              :          * unmatched MCVs that are assumed to match against random members of
    2646              :          * relation 2's non-MCV population, plus non-MCV values that are
    2647              :          * assumed to match against random members of relation 2's unmatched
    2648              :          * MCVs plus non-MCV values.
    2649              :          */
    2650        15032 :         totalsel1 = matchprodfreq;
    2651        15032 :         if (nd2 > sslot2->nvalues)
    2652         3387 :             totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->nvalues);
    2653        15032 :         if (nd2 > nmatches)
    2654         6352 :             totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) /
    2655         6352 :                 (nd2 - nmatches);
    2656              :         /* Same estimate from the point of view of relation 2. */
    2657        15032 :         totalsel2 = matchprodfreq;
    2658        15032 :         if (nd1 > sslot1->nvalues)
    2659         4364 :             totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->nvalues);
    2660        15032 :         if (nd1 > nmatches)
    2661         5570 :             totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) /
    2662         5570 :                 (nd1 - nmatches);
    2663              : 
    2664              :         /*
    2665              :          * Use the smaller of the two estimates.  This can be justified in
    2666              :          * essentially the same terms as given below for the no-stats case: to
    2667              :          * a first approximation, we are estimating from the point of view of
    2668              :          * the relation with smaller nd.
    2669              :          */
    2670        15032 :         selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
    2671              :     }
    2672              :     else
    2673              :     {
    2674              :         /*
    2675              :          * We do not have MCV lists for both sides.  Estimate the join
    2676              :          * selectivity as MIN(1/nd1,1/nd2)*(1-nullfrac1)*(1-nullfrac2). This
    2677              :          * is plausible if we assume that the join operator is strict and the
    2678              :          * non-null values are about equally distributed: a given non-null
    2679              :          * tuple of rel1 will join to either zero or N2*(1-nullfrac2)/nd2 rows
    2680              :          * of rel2, so total join rows are at most
    2681              :          * N1*(1-nullfrac1)*N2*(1-nullfrac2)/nd2 giving a join selectivity of
    2682              :          * not more than (1-nullfrac1)*(1-nullfrac2)/nd2. By the same logic it
    2683              :          * is not more than (1-nullfrac1)*(1-nullfrac2)/nd1, so the expression
    2684              :          * with MIN() is an upper bound.  Using the MIN() means we estimate
    2685              :          * from the point of view of the relation with smaller nd (since the
    2686              :          * larger nd is determining the MIN).  It is reasonable to assume that
    2687              :          * most tuples in this rel will have join partners, so the bound is
    2688              :          * probably reasonably tight and should be taken as-is.
    2689              :          *
    2690              :          * XXX Can we be smarter if we have an MCV list for just one side? It
    2691              :          * seems that if we assume equal distribution for the other side, we
    2692              :          * end up with the same answer anyway.
    2693              :          */
    2694       139294 :         double      nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
    2695       139294 :         double      nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
    2696              : 
    2697       139294 :         selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
    2698       139294 :         if (nd1 > nd2)
    2699        70433 :             selec /= nd1;
    2700              :         else
    2701        68861 :             selec /= nd2;
    2702              :     }
    2703              : 
    2704       154326 :     return selec;
    2705              : }
    2706              : 
    2707              : /*
    2708              :  * eqjoinsel_semi --- eqjoinsel for semi join
    2709              :  *
    2710              :  * (Also used for anti join, which we are supposed to estimate the same way.)
    2711              :  * Caller has ensured that vardata1 is the LHS variable; however, eqproc
    2712              :  * is for the original join operator, which might now need to have the inputs
    2713              :  * swapped in order to apply correctly.  Also, if have_mcvs1 && have_mcvs2
    2714              :  * then hasmatch1[], hasmatch2[], and *p_nmatches were filled by
    2715              :  * eqjoinsel_inner.
    2716              :  */
    2717              : static double
    2718         7250 : eqjoinsel_semi(FmgrInfo *eqproc, Oid collation,
    2719              :                Oid hashLeft, Oid hashRight,
    2720              :                bool op_is_reversed,
    2721              :                VariableStatData *vardata1, VariableStatData *vardata2,
    2722              :                double nd1, double nd2,
    2723              :                bool isdefault1, bool isdefault2,
    2724              :                AttStatsSlot *sslot1, AttStatsSlot *sslot2,
    2725              :                Form_pg_statistic stats1, Form_pg_statistic stats2,
    2726              :                bool have_mcvs1, bool have_mcvs2,
    2727              :                bool *hasmatch1, bool *hasmatch2,
    2728              :                int *p_nmatches,
    2729              :                RelOptInfo *inner_rel)
    2730              : {
    2731              :     double      selec;
    2732              : 
    2733              :     /*
    2734              :      * We clamp nd2 to be not more than what we estimate the inner relation's
    2735              :      * size to be.  This is intuitively somewhat reasonable since obviously
    2736              :      * there can't be more than that many distinct values coming from the
    2737              :      * inner rel.  The reason for the asymmetry (ie, that we don't clamp nd1
    2738              :      * likewise) is that this is the only pathway by which restriction clauses
    2739              :      * applied to the inner rel will affect the join result size estimate,
    2740              :      * since set_joinrel_size_estimates will multiply SEMI/ANTI selectivity by
    2741              :      * only the outer rel's size.  If we clamped nd1 we'd be double-counting
    2742              :      * the selectivity of outer-rel restrictions.
    2743              :      *
    2744              :      * We can apply this clamping both with respect to the base relation from
    2745              :      * which the join variable comes (if there is just one), and to the
    2746              :      * immediate inner input relation of the current join.
    2747              :      *
    2748              :      * If we clamp, we can treat nd2 as being a non-default estimate; it's not
    2749              :      * great, maybe, but it didn't come out of nowhere either.  This is most
    2750              :      * helpful when the inner relation is empty and consequently has no stats.
    2751              :      */
    2752         7250 :     if (vardata2->rel)
    2753              :     {
    2754         7247 :         if (nd2 >= vardata2->rel->rows)
    2755              :         {
    2756         6171 :             nd2 = vardata2->rel->rows;
    2757         6171 :             isdefault2 = false;
    2758              :         }
    2759              :     }
    2760         7250 :     if (nd2 >= inner_rel->rows)
    2761              :     {
    2762         6142 :         nd2 = inner_rel->rows;
    2763         6142 :         isdefault2 = false;
    2764              :     }
    2765              : 
    2766         7250 :     if (have_mcvs1 && have_mcvs2)
    2767          309 :     {
    2768              :         /*
    2769              :          * We have most-common-value lists for both relations.  Run through
    2770              :          * the lists to see which MCVs actually join to each other with the
    2771              :          * given operator.  This allows us to determine the exact join
    2772              :          * selectivity for the portion of the relations represented by the MCV
    2773              :          * lists.  We still have to estimate for the remaining population, but
    2774              :          * in a skewed distribution this gives us a big leg up in accuracy.
    2775              :          */
    2776          309 :         double      nullfrac1 = stats1->stanullfrac;
    2777              :         double      matchprodfreq,
    2778              :                     matchfreq1,
    2779              :                     uncertainfrac,
    2780              :                     uncertain;
    2781              :         int         i,
    2782              :                     nmatches,
    2783              :                     clamped_nvalues2;
    2784              : 
    2785              :         /*
    2786              :          * The clamping above could have resulted in nd2 being less than
    2787              :          * sslot2->nvalues; in which case, we assume that precisely the nd2
    2788              :          * most common values in the relation will appear in the join input,
    2789              :          * and so compare to only the first nd2 members of the MCV list.  Of
    2790              :          * course this is frequently wrong, but it's the best bet we can make.
    2791              :          */
    2792          309 :         clamped_nvalues2 = Min(sslot2->nvalues, nd2);
    2793              : 
    2794              :         /*
    2795              :          * If we did not set clamped_nvalues2 to less than sslot2->nvalues,
    2796              :          * then the hasmatch1[] and hasmatch2[] match flags computed by
    2797              :          * eqjoinsel_inner are still perfectly applicable, so we need not
    2798              :          * re-do the matching work.  Note that it does not matter if
    2799              :          * op_is_reversed: we'd get the same answers.
    2800              :          *
    2801              :          * If we did clamp, then a different set of sslot2 values is to be
    2802              :          * compared, so we have to re-do the matching.
    2803              :          */
    2804          309 :         if (clamped_nvalues2 != sslot2->nvalues)
    2805              :         {
    2806              :             /* Must re-zero the arrays */
    2807            0 :             memset(hasmatch1, 0, sslot1->nvalues * sizeof(bool));
    2808            0 :             memset(hasmatch2, 0, clamped_nvalues2 * sizeof(bool));
    2809              :             /* Re-fill the match arrays */
    2810            0 :             eqjoinsel_find_matches(eqproc, collation,
    2811              :                                    hashLeft, hashRight,
    2812              :                                    op_is_reversed,
    2813              :                                    sslot1, sslot2,
    2814              :                                    sslot1->nvalues, clamped_nvalues2,
    2815              :                                    hasmatch1, hasmatch2,
    2816              :                                    p_nmatches, &matchprodfreq);
    2817              :         }
    2818          309 :         nmatches = *p_nmatches;
    2819              : 
    2820              :         /* Sum up frequencies of matched MCVs */
    2821          309 :         matchfreq1 = 0.0;
    2822         6776 :         for (i = 0; i < sslot1->nvalues; i++)
    2823              :         {
    2824         6467 :             if (hasmatch1[i])
    2825         5740 :                 matchfreq1 += sslot1->numbers[i];
    2826              :         }
    2827          309 :         CLAMP_PROBABILITY(matchfreq1);
    2828              : 
    2829              :         /*
    2830              :          * Now we need to estimate the fraction of relation 1 that has at
    2831              :          * least one join partner.  We know for certain that the matched MCVs
    2832              :          * do, so that gives us a lower bound, but we're really in the dark
    2833              :          * about everything else.  Our crude approach is: if nd1 <= nd2 then
    2834              :          * assume all non-null rel1 rows have join partners, else assume for
    2835              :          * the uncertain rows that a fraction nd2/nd1 have join partners. We
    2836              :          * can discount the known-matched MCVs from the distinct-values counts
    2837              :          * before doing the division.
    2838              :          *
    2839              :          * Crude as the above is, it's completely useless if we don't have
    2840              :          * reliable ndistinct values for both sides.  Hence, if either nd1 or
    2841              :          * nd2 is default, punt and assume half of the uncertain rows have
    2842              :          * join partners.
    2843              :          */
    2844          309 :         if (!isdefault1 && !isdefault2)
    2845              :         {
    2846          309 :             nd1 -= nmatches;
    2847          309 :             nd2 -= nmatches;
    2848          309 :             if (nd1 <= nd2 || nd2 < 0)
    2849          291 :                 uncertainfrac = 1.0;
    2850              :             else
    2851           18 :                 uncertainfrac = nd2 / nd1;
    2852              :         }
    2853              :         else
    2854            0 :             uncertainfrac = 0.5;
    2855          309 :         uncertain = 1.0 - matchfreq1 - nullfrac1;
    2856          309 :         CLAMP_PROBABILITY(uncertain);
    2857          309 :         selec = matchfreq1 + uncertainfrac * uncertain;
    2858              :     }
    2859              :     else
    2860              :     {
    2861              :         /*
    2862              :          * Without MCV lists for both sides, we can only use the heuristic
    2863              :          * about nd1 vs nd2.
    2864              :          */
    2865         6941 :         double      nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
    2866              : 
    2867         6941 :         if (!isdefault1 && !isdefault2)
    2868              :         {
    2869         5231 :             if (nd1 <= nd2 || nd2 < 0)
    2870         2568 :                 selec = 1.0 - nullfrac1;
    2871              :             else
    2872         2663 :                 selec = (nd2 / nd1) * (1.0 - nullfrac1);
    2873              :         }
    2874              :         else
    2875         1710 :             selec = 0.5 * (1.0 - nullfrac1);
    2876              :     }
    2877              : 
    2878         7250 :     return selec;
    2879              : }
    2880              : 
    2881              : /*
    2882              :  * Identify matching MCVs for eqjoinsel_inner or eqjoinsel_semi.
    2883              :  *
    2884              :  * Inputs:
    2885              :  *  eqproc: FmgrInfo for equality function to use (might be reversed)
    2886              :  *  collation: OID of collation to use
    2887              :  *  hashLeft, hashRight: OIDs of hash functions associated with equality op,
    2888              :  *      or InvalidOid if we're not to use hashing
    2889              :  *  op_is_reversed: indicates that eqproc compares right type to left type
    2890              :  *  sslot1, sslot2: MCV values for the lefthand and righthand inputs
    2891              :  *  nvalues1, nvalues2: number of values to be considered (can be less than
    2892              :  *      sslotN->nvalues, but not more)
    2893              :  * Outputs:
    2894              :  *  hasmatch1[], hasmatch2[]: pre-zeroed arrays of lengths nvalues1, nvalues2;
    2895              :  *      entries are set to true if that MCV has a match on the other side
    2896              :  *  *p_nmatches: receives number of MCV pairs that match
    2897              :  *  *p_matchprodfreq: receives sum(sslot1->numbers[i] * sslot2->numbers[j])
    2898              :  *      for matching MCVs
    2899              :  *
    2900              :  * Note that hashLeft is for the eqproc's left-hand input type, hashRight
    2901              :  * for its right, regardless of op_is_reversed.
    2902              :  *
    2903              :  * Note we assume that each MCV will match at most one member of the other
    2904              :  * MCV list.  If the operator isn't really equality, there could be multiple
    2905              :  * matches --- but we don't look for them, both for speed and because the
    2906              :  * math wouldn't add up...
    2907              :  */
    2908              : static void
    2909        15032 : eqjoinsel_find_matches(FmgrInfo *eqproc, Oid collation,
    2910              :                        Oid hashLeft, Oid hashRight,
    2911              :                        bool op_is_reversed,
    2912              :                        AttStatsSlot *sslot1, AttStatsSlot *sslot2,
    2913              :                        int nvalues1, int nvalues2,
    2914              :                        bool *hasmatch1, bool *hasmatch2,
    2915              :                        int *p_nmatches, double *p_matchprodfreq)
    2916              : {
    2917        15032 :     LOCAL_FCINFO(fcinfo, 2);
    2918        15032 :     double      matchprodfreq = 0.0;
    2919        15032 :     int         nmatches = 0;
    2920              : 
    2921              :     /*
    2922              :      * Save a few cycles by setting up the fcinfo struct just once.  Using
    2923              :      * FunctionCallInvoke directly also avoids failure if the eqproc returns
    2924              :      * NULL, though really equality functions should never do that.
    2925              :      */
    2926        15032 :     InitFunctionCallInfoData(*fcinfo, eqproc, 2, collation,
    2927              :                              NULL, NULL);
    2928        15032 :     fcinfo->args[0].isnull = false;
    2929        15032 :     fcinfo->args[1].isnull = false;
    2930              : 
    2931        15032 :     if (OidIsValid(hashLeft) && OidIsValid(hashRight))
    2932          967 :     {
    2933              :         /* Use a hash table to speed up the matching */
    2934          967 :         LOCAL_FCINFO(hash_fcinfo, 1);
    2935              :         FmgrInfo    hash_proc;
    2936              :         MCVHashContext hashContext;
    2937              :         MCVHashTable_hash *hashTable;
    2938              :         AttStatsSlot *statsProbe;
    2939              :         AttStatsSlot *statsHash;
    2940              :         bool       *hasMatchProbe;
    2941              :         bool       *hasMatchHash;
    2942              :         int         nvaluesProbe;
    2943              :         int         nvaluesHash;
    2944              : 
    2945              :         /* Make sure we build the hash table on the smaller array. */
    2946          967 :         if (sslot1->nvalues >= sslot2->nvalues)
    2947              :         {
    2948          967 :             statsProbe = sslot1;
    2949          967 :             statsHash = sslot2;
    2950          967 :             hasMatchProbe = hasmatch1;
    2951          967 :             hasMatchHash = hasmatch2;
    2952          967 :             nvaluesProbe = nvalues1;
    2953          967 :             nvaluesHash = nvalues2;
    2954              :         }
    2955              :         else
    2956              :         {
    2957              :             /* We'll have to reverse the direction of use of the operator. */
    2958            0 :             op_is_reversed = !op_is_reversed;
    2959            0 :             statsProbe = sslot2;
    2960            0 :             statsHash = sslot1;
    2961            0 :             hasMatchProbe = hasmatch2;
    2962            0 :             hasMatchHash = hasmatch1;
    2963            0 :             nvaluesProbe = nvalues2;
    2964            0 :             nvaluesHash = nvalues1;
    2965              :         }
    2966              : 
    2967              :         /*
    2968              :          * Build the hash table on the smaller array, using the appropriate
    2969              :          * hash function for its data type.
    2970              :          */
    2971          967 :         fmgr_info(op_is_reversed ? hashLeft : hashRight, &hash_proc);
    2972          967 :         InitFunctionCallInfoData(*hash_fcinfo, &hash_proc, 1, collation,
    2973              :                                  NULL, NULL);
    2974          967 :         hash_fcinfo->args[0].isnull = false;
    2975              : 
    2976          967 :         hashContext.equal_fcinfo = fcinfo;
    2977          967 :         hashContext.hash_fcinfo = hash_fcinfo;
    2978          967 :         hashContext.op_is_reversed = op_is_reversed;
    2979          967 :         hashContext.insert_mode = true;
    2980          967 :         get_typlenbyval(statsHash->valuetype,
    2981              :                         &hashContext.hash_typlen,
    2982              :                         &hashContext.hash_typbyval);
    2983              : 
    2984          967 :         hashTable = MCVHashTable_create(CurrentMemoryContext,
    2985              :                                         nvaluesHash,
    2986              :                                         &hashContext);
    2987              : 
    2988        97667 :         for (int i = 0; i < nvaluesHash; i++)
    2989              :         {
    2990        96700 :             bool        found = false;
    2991        96700 :             MCVHashEntry *entry = MCVHashTable_insert(hashTable,
    2992        96700 :                                                       statsHash->values[i],
    2993              :                                                       &found);
    2994              : 
    2995              :             /*
    2996              :              * MCVHashTable_insert will only report "found" if the new value
    2997              :              * is equal to some previous one per datum_image_eq().  That
    2998              :              * probably shouldn't happen, since we're not expecting duplicates
    2999              :              * in the MCV list.  If we do find a dup, just ignore it, leaving
    3000              :              * the hash entry's index pointing at the first occurrence.  That
    3001              :              * matches the behavior that the non-hashed code path would have.
    3002              :              */
    3003        96700 :             if (likely(!found))
    3004        96700 :                 entry->index = i;
    3005              :         }
    3006              : 
    3007              :         /*
    3008              :          * Prepare to probe the hash table.  If the probe values are of a
    3009              :          * different data type, then we need to change hash functions.  (This
    3010              :          * code relies on the assumption that since we defined SH_STORE_HASH,
    3011              :          * simplehash.h will never need to compute hash values for existing
    3012              :          * hash table entries.)
    3013              :          */
    3014          967 :         hashContext.insert_mode = false;
    3015          967 :         if (hashLeft != hashRight)
    3016              :         {
    3017            0 :             fmgr_info(op_is_reversed ? hashRight : hashLeft, &hash_proc);
    3018              :             /* Resetting hash_fcinfo is probably unnecessary, but be safe */
    3019            0 :             InitFunctionCallInfoData(*hash_fcinfo, &hash_proc, 1, collation,
    3020              :                                      NULL, NULL);
    3021            0 :             hash_fcinfo->args[0].isnull = false;
    3022              :         }
    3023              : 
    3024              :         /* Look up each probe value in turn. */
    3025        97667 :         for (int i = 0; i < nvaluesProbe; i++)
    3026              :         {
    3027        96700 :             MCVHashEntry *entry = MCVHashTable_lookup(hashTable,
    3028        96700 :                                                       statsProbe->values[i]);
    3029              : 
    3030              :             /* As in the other code path, skip already-matched hash entries */
    3031        96700 :             if (entry != NULL && !hasMatchHash[entry->index])
    3032              :             {
    3033        34444 :                 hasMatchHash[entry->index] = hasMatchProbe[i] = true;
    3034        34444 :                 nmatches++;
    3035        34444 :                 matchprodfreq += statsHash->numbers[entry->index] * statsProbe->numbers[i];
    3036              :             }
    3037              :         }
    3038              : 
    3039          967 :         MCVHashTable_destroy(hashTable);
    3040              :     }
    3041              :     else
    3042              :     {
    3043              :         /* We're not to use hashing, so do it the O(N^2) way */
    3044              :         int         index1,
    3045              :                     index2;
    3046              : 
    3047              :         /* Set up to supply the values in the order the operator expects */
    3048        14065 :         if (op_is_reversed)
    3049              :         {
    3050            0 :             index1 = 1;
    3051            0 :             index2 = 0;
    3052              :         }
    3053              :         else
    3054              :         {
    3055        14065 :             index1 = 0;
    3056        14065 :             index2 = 1;
    3057              :         }
    3058              : 
    3059       326264 :         for (int i = 0; i < nvalues1; i++)
    3060              :         {
    3061       312199 :             fcinfo->args[index1].value = sslot1->values[i];
    3062              : 
    3063      6907422 :             for (int j = 0; j < nvalues2; j++)
    3064              :             {
    3065              :                 Datum       fresult;
    3066              : 
    3067      6723899 :                 if (hasmatch2[j])
    3068      1949424 :                     continue;
    3069      4774475 :                 fcinfo->args[index2].value = sslot2->values[j];
    3070      4774475 :                 fcinfo->isnull = false;
    3071      4774475 :                 fresult = FunctionCallInvoke(fcinfo);
    3072      4774475 :                 if (!fcinfo->isnull && DatumGetBool(fresult))
    3073              :                 {
    3074       128676 :                     hasmatch1[i] = hasmatch2[j] = true;
    3075       128676 :                     matchprodfreq += sslot1->numbers[i] * sslot2->numbers[j];
    3076       128676 :                     nmatches++;
    3077       128676 :                     break;
    3078              :                 }
    3079              :             }
    3080              :         }
    3081              :     }
    3082              : 
    3083        15032 :     *p_nmatches = nmatches;
    3084        15032 :     *p_matchprodfreq = matchprodfreq;
    3085        15032 : }
    3086              : 
    3087              : /*
    3088              :  * Support functions for the hash tables used by eqjoinsel_find_matches
    3089              :  */
    3090              : static uint32
    3091       193400 : hash_mcv(MCVHashTable_hash *tab, Datum key)
    3092              : {
    3093       193400 :     MCVHashContext *context = (MCVHashContext *) tab->private_data;
    3094       193400 :     FunctionCallInfo fcinfo = context->hash_fcinfo;
    3095              :     Datum       fresult;
    3096              : 
    3097       193400 :     fcinfo->args[0].value = key;
    3098       193400 :     fcinfo->isnull = false;
    3099       193400 :     fresult = FunctionCallInvoke(fcinfo);
    3100              :     Assert(!fcinfo->isnull);
    3101       193400 :     return DatumGetUInt32(fresult);
    3102              : }
    3103              : 
    3104              : static bool
    3105        34444 : mcvs_equal(MCVHashTable_hash *tab, Datum key0, Datum key1)
    3106              : {
    3107        34444 :     MCVHashContext *context = (MCVHashContext *) tab->private_data;
    3108              : 
    3109        34444 :     if (context->insert_mode)
    3110              :     {
    3111              :         /*
    3112              :          * During the insertion step, any comparisons will be between two
    3113              :          * Datums of the hash table's data type, so if the given operator is
    3114              :          * cross-type it will be the wrong thing to use.  Fortunately, we can
    3115              :          * use datum_image_eq instead.  The MCV values should all be distinct
    3116              :          * anyway, so it's mostly pro-forma to compare them at all.
    3117              :          */
    3118            0 :         return datum_image_eq(key0, key1,
    3119            0 :                               context->hash_typbyval, context->hash_typlen);
    3120              :     }
    3121              :     else
    3122              :     {
    3123        34444 :         FunctionCallInfo fcinfo = context->equal_fcinfo;
    3124              :         Datum       fresult;
    3125              : 
    3126              :         /*
    3127              :          * Apply the operator the correct way around.  Although simplehash.h
    3128              :          * doesn't document this explicitly, during lookups key0 is from the
    3129              :          * hash table while key1 is the probe value, so we should compare them
    3130              :          * in that order only if op_is_reversed.
    3131              :          */
    3132        34444 :         if (context->op_is_reversed)
    3133              :         {
    3134            0 :             fcinfo->args[0].value = key0;
    3135            0 :             fcinfo->args[1].value = key1;
    3136              :         }
    3137              :         else
    3138              :         {
    3139        34444 :             fcinfo->args[0].value = key1;
    3140        34444 :             fcinfo->args[1].value = key0;
    3141              :         }
    3142        34444 :         fcinfo->isnull = false;
    3143        34444 :         fresult = FunctionCallInvoke(fcinfo);
    3144        34444 :         return (!fcinfo->isnull && DatumGetBool(fresult));
    3145              :     }
    3146              : }
    3147              : 
    3148              : /*
    3149              :  *      neqjoinsel      - Join selectivity of "!="
    3150              :  */
    3151              : Datum
    3152         2471 : neqjoinsel(PG_FUNCTION_ARGS)
    3153              : {
    3154         2471 :     PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
    3155         2471 :     Oid         operator = PG_GETARG_OID(1);
    3156         2471 :     List       *args = (List *) PG_GETARG_POINTER(2);
    3157         2471 :     JoinType    jointype = (JoinType) PG_GETARG_INT16(3);
    3158         2471 :     SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) PG_GETARG_POINTER(4);
    3159         2471 :     Oid         collation = PG_GET_COLLATION();
    3160              :     float8      result;
    3161              : 
    3162         2471 :     if (jointype == JOIN_SEMI || jointype == JOIN_ANTI)
    3163          827 :     {
    3164              :         /*
    3165              :          * For semi-joins, if there is more than one distinct value in the RHS
    3166              :          * relation then every non-null LHS row must find a row to join since
    3167              :          * it can only be equal to one of them.  We'll assume that there is
    3168              :          * always more than one distinct RHS value for the sake of stability,
    3169              :          * though in theory we could have special cases for empty RHS
    3170              :          * (selectivity = 0) and single-distinct-value RHS (selectivity =
    3171              :          * fraction of LHS that has the same value as the single RHS value).
    3172              :          *
    3173              :          * For anti-joins, if we use the same assumption that there is more
    3174              :          * than one distinct key in the RHS relation, then every non-null LHS
    3175              :          * row must be suppressed by the anti-join.
    3176              :          *
    3177              :          * So either way, the selectivity estimate should be 1 - nullfrac.
    3178              :          */
    3179              :         VariableStatData leftvar;
    3180              :         VariableStatData rightvar;
    3181              :         bool        reversed;
    3182              :         HeapTuple   statsTuple;
    3183              :         double      nullfrac;
    3184              : 
    3185          827 :         get_join_variables(root, args, sjinfo, &leftvar, &rightvar, &reversed);
    3186          827 :         statsTuple = reversed ? rightvar.statsTuple : leftvar.statsTuple;
    3187          827 :         if (HeapTupleIsValid(statsTuple))
    3188          706 :             nullfrac = ((Form_pg_statistic) GETSTRUCT(statsTuple))->stanullfrac;
    3189              :         else
    3190          121 :             nullfrac = 0.0;
    3191          827 :         ReleaseVariableStats(leftvar);
    3192          827 :         ReleaseVariableStats(rightvar);
    3193              : 
    3194          827 :         result = 1.0 - nullfrac;
    3195              :     }
    3196              :     else
    3197              :     {
    3198              :         /*
    3199              :          * We want 1 - eqjoinsel() where the equality operator is the one
    3200              :          * associated with this != operator, that is, its negator.
    3201              :          */
    3202         1644 :         Oid         eqop = get_negator(operator);
    3203              : 
    3204         1644 :         if (eqop)
    3205              :         {
    3206              :             result =
    3207         1644 :                 DatumGetFloat8(DirectFunctionCall5Coll(eqjoinsel,
    3208              :                                                        collation,
    3209              :                                                        PointerGetDatum(root),
    3210              :                                                        ObjectIdGetDatum(eqop),
    3211              :                                                        PointerGetDatum(args),
    3212              :                                                        Int16GetDatum(jointype),
    3213              :                                                        PointerGetDatum(sjinfo)));
    3214              :         }
    3215              :         else
    3216              :         {
    3217              :             /* Use default selectivity (should we raise an error instead?) */
    3218            0 :             result = DEFAULT_EQ_SEL;
    3219              :         }
    3220         1644 :         result = 1.0 - result;
    3221              :     }
    3222              : 
    3223         2471 :     PG_RETURN_FLOAT8(result);
    3224              : }
    3225              : 
    3226              : /*
    3227              :  *      scalarltjoinsel - Join selectivity of "<" for scalars
    3228              :  */
    3229              : Datum
    3230          162 : scalarltjoinsel(PG_FUNCTION_ARGS)
    3231              : {
    3232          162 :     PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    3233              : }
    3234              : 
    3235              : /*
    3236              :  *      scalarlejoinsel - Join selectivity of "<=" for scalars
    3237              :  */
    3238              : Datum
    3239          138 : scalarlejoinsel(PG_FUNCTION_ARGS)
    3240              : {
    3241          138 :     PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    3242              : }
    3243              : 
    3244              : /*
    3245              :  *      scalargtjoinsel - Join selectivity of ">" for scalars
    3246              :  */
    3247              : Datum
    3248          138 : scalargtjoinsel(PG_FUNCTION_ARGS)
    3249              : {
    3250          138 :     PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    3251              : }
    3252              : 
    3253              : /*
    3254              :  *      scalargejoinsel - Join selectivity of ">=" for scalars
    3255              :  */
    3256              : Datum
    3257           92 : scalargejoinsel(PG_FUNCTION_ARGS)
    3258              : {
    3259           92 :     PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
    3260              : }
    3261              : 
    3262              : 
    3263              : /*
    3264              :  * mergejoinscansel         - Scan selectivity of merge join.
    3265              :  *
    3266              :  * A merge join will stop as soon as it exhausts either input stream.
    3267              :  * Therefore, if we can estimate the ranges of both input variables,
    3268              :  * we can estimate how much of the input will actually be read.  This
    3269              :  * can have a considerable impact on the cost when using indexscans.
    3270              :  *
    3271              :  * Also, we can estimate how much of each input has to be read before the
    3272              :  * first join pair is found, which will affect the join's startup time.
    3273              :  *
    3274              :  * clause should be a clause already known to be mergejoinable.  opfamily,
    3275              :  * cmptype, and nulls_first specify the sort ordering being used.
    3276              :  *
    3277              :  * The outputs are:
    3278              :  *      *leftstart is set to the fraction of the left-hand variable expected
    3279              :  *       to be scanned before the first join pair is found (0 to 1).
    3280              :  *      *leftend is set to the fraction of the left-hand variable expected
    3281              :  *       to be scanned before the join terminates (0 to 1).
    3282              :  *      *rightstart, *rightend similarly for the right-hand variable.
    3283              :  */
    3284              : void
    3285        81576 : mergejoinscansel(PlannerInfo *root, Node *clause,
    3286              :                  Oid opfamily, CompareType cmptype, bool nulls_first,
    3287              :                  Selectivity *leftstart, Selectivity *leftend,
    3288              :                  Selectivity *rightstart, Selectivity *rightend)
    3289              : {
    3290              :     Node       *left,
    3291              :                *right;
    3292              :     VariableStatData leftvar,
    3293              :                 rightvar;
    3294              :     Oid         opmethod;
    3295              :     int         op_strategy;
    3296              :     Oid         op_lefttype;
    3297              :     Oid         op_righttype;
    3298              :     Oid         opno,
    3299              :                 collation,
    3300              :                 lsortop,
    3301              :                 rsortop,
    3302              :                 lstatop,
    3303              :                 rstatop,
    3304              :                 ltop,
    3305              :                 leop,
    3306              :                 revltop,
    3307              :                 revleop;
    3308              :     StrategyNumber ltstrat,
    3309              :                 lestrat,
    3310              :                 gtstrat,
    3311              :                 gestrat;
    3312              :     bool        isgt;
    3313              :     Datum       leftmin,
    3314              :                 leftmax,
    3315              :                 rightmin,
    3316              :                 rightmax;
    3317              :     double      selec;
    3318              : 
    3319              :     /* Set default results if we can't figure anything out. */
    3320              :     /* XXX should default "start" fraction be a bit more than 0? */
    3321        81576 :     *leftstart = *rightstart = 0.0;
    3322        81576 :     *leftend = *rightend = 1.0;
    3323              : 
    3324              :     /* Deconstruct the merge clause */
    3325        81576 :     if (!is_opclause(clause))
    3326            0 :         return;                 /* shouldn't happen */
    3327        81576 :     opno = ((OpExpr *) clause)->opno;
    3328        81576 :     collation = ((OpExpr *) clause)->inputcollid;
    3329        81576 :     left = get_leftop((Expr *) clause);
    3330        81576 :     right = get_rightop((Expr *) clause);
    3331        81576 :     if (!right)
    3332            0 :         return;                 /* shouldn't happen */
    3333              : 
    3334              :     /* Look for stats for the inputs */
    3335        81576 :     examine_variable(root, left, 0, &leftvar);
    3336        81576 :     examine_variable(root, right, 0, &rightvar);
    3337              : 
    3338        81576 :     opmethod = get_opfamily_method(opfamily);
    3339              : 
    3340              :     /* Extract the operator's declared left/right datatypes */
    3341        81576 :     get_op_opfamily_properties(opno, opfamily, false,
    3342              :                                &op_strategy,
    3343              :                                &op_lefttype,
    3344              :                                &op_righttype);
    3345              :     Assert(IndexAmTranslateStrategy(op_strategy, opmethod, opfamily, true) == COMPARE_EQ);
    3346              : 
    3347              :     /*
    3348              :      * Look up the various operators we need.  If we don't find them all, it
    3349              :      * probably means the opfamily is broken, but we just fail silently.
    3350              :      *
    3351              :      * Note: we expect that pg_statistic histograms will be sorted by the '<'
    3352              :      * operator, regardless of which sort direction we are considering.
    3353              :      */
    3354        81576 :     switch (cmptype)
    3355              :     {
    3356        81558 :         case COMPARE_LT:
    3357        81558 :             isgt = false;
    3358        81558 :             ltstrat = IndexAmTranslateCompareType(COMPARE_LT, opmethod, opfamily, true);
    3359        81558 :             lestrat = IndexAmTranslateCompareType(COMPARE_LE, opmethod, opfamily, true);
    3360        81558 :             if (op_lefttype == op_righttype)
    3361              :             {
    3362              :                 /* easy case */
    3363        80532 :                 ltop = get_opfamily_member(opfamily,
    3364              :                                            op_lefttype, op_righttype,
    3365              :                                            ltstrat);
    3366        80532 :                 leop = get_opfamily_member(opfamily,
    3367              :                                            op_lefttype, op_righttype,
    3368              :                                            lestrat);
    3369        80532 :                 lsortop = ltop;
    3370        80532 :                 rsortop = ltop;
    3371        80532 :                 lstatop = lsortop;
    3372        80532 :                 rstatop = rsortop;
    3373        80532 :                 revltop = ltop;
    3374        80532 :                 revleop = leop;
    3375              :             }
    3376              :             else
    3377              :             {
    3378         1026 :                 ltop = get_opfamily_member(opfamily,
    3379              :                                            op_lefttype, op_righttype,
    3380              :                                            ltstrat);
    3381         1026 :                 leop = get_opfamily_member(opfamily,
    3382              :                                            op_lefttype, op_righttype,
    3383              :                                            lestrat);
    3384         1026 :                 lsortop = get_opfamily_member(opfamily,
    3385              :                                               op_lefttype, op_lefttype,
    3386              :                                               ltstrat);
    3387         1026 :                 rsortop = get_opfamily_member(opfamily,
    3388              :                                               op_righttype, op_righttype,
    3389              :                                               ltstrat);
    3390         1026 :                 lstatop = lsortop;
    3391         1026 :                 rstatop = rsortop;
    3392         1026 :                 revltop = get_opfamily_member(opfamily,
    3393              :                                               op_righttype, op_lefttype,
    3394              :                                               ltstrat);
    3395         1026 :                 revleop = get_opfamily_member(opfamily,
    3396              :                                               op_righttype, op_lefttype,
    3397              :                                               lestrat);
    3398              :             }
    3399        81558 :             break;
    3400           18 :         case COMPARE_GT:
    3401              :             /* descending-order case */
    3402           18 :             isgt = true;
    3403           18 :             ltstrat = IndexAmTranslateCompareType(COMPARE_LT, opmethod, opfamily, true);
    3404           18 :             gtstrat = IndexAmTranslateCompareType(COMPARE_GT, opmethod, opfamily, true);
    3405           18 :             gestrat = IndexAmTranslateCompareType(COMPARE_GE, opmethod, opfamily, true);
    3406           18 :             if (op_lefttype == op_righttype)
    3407              :             {
    3408              :                 /* easy case */
    3409           18 :                 ltop = get_opfamily_member(opfamily,
    3410              :                                            op_lefttype, op_righttype,
    3411              :                                            gtstrat);
    3412           18 :                 leop = get_opfamily_member(opfamily,
    3413              :                                            op_lefttype, op_righttype,
    3414              :                                            gestrat);
    3415           18 :                 lsortop = ltop;
    3416           18 :                 rsortop = ltop;
    3417           18 :                 lstatop = get_opfamily_member(opfamily,
    3418              :                                               op_lefttype, op_lefttype,
    3419              :                                               ltstrat);
    3420           18 :                 rstatop = lstatop;
    3421           18 :                 revltop = ltop;
    3422           18 :                 revleop = leop;
    3423              :             }
    3424              :             else
    3425              :             {
    3426            0 :                 ltop = get_opfamily_member(opfamily,
    3427              :                                            op_lefttype, op_righttype,
    3428              :                                            gtstrat);
    3429            0 :                 leop = get_opfamily_member(opfamily,
    3430              :                                            op_lefttype, op_righttype,
    3431              :                                            gestrat);
    3432            0 :                 lsortop = get_opfamily_member(opfamily,
    3433              :                                               op_lefttype, op_lefttype,
    3434              :                                               gtstrat);
    3435            0 :                 rsortop = get_opfamily_member(opfamily,
    3436              :                                               op_righttype, op_righttype,
    3437              :                                               gtstrat);
    3438            0 :                 lstatop = get_opfamily_member(opfamily,
    3439              :                                               op_lefttype, op_lefttype,
    3440              :                                               ltstrat);
    3441            0 :                 rstatop = get_opfamily_member(opfamily,
    3442              :                                               op_righttype, op_righttype,
    3443              :                                               ltstrat);
    3444            0 :                 revltop = get_opfamily_member(opfamily,
    3445              :                                               op_righttype, op_lefttype,
    3446              :                                               gtstrat);
    3447            0 :                 revleop = get_opfamily_member(opfamily,
    3448              :                                               op_righttype, op_lefttype,
    3449              :                                               gestrat);
    3450              :             }
    3451           18 :             break;
    3452            0 :         default:
    3453            0 :             goto fail;          /* shouldn't get here */
    3454              :     }
    3455              : 
    3456        81576 :     if (!OidIsValid(lsortop) ||
    3457        81576 :         !OidIsValid(rsortop) ||
    3458        81576 :         !OidIsValid(lstatop) ||
    3459        81576 :         !OidIsValid(rstatop) ||
    3460        81570 :         !OidIsValid(ltop) ||
    3461        81570 :         !OidIsValid(leop) ||
    3462        81570 :         !OidIsValid(revltop) ||
    3463              :         !OidIsValid(revleop))
    3464            6 :         goto fail;              /* insufficient info in catalogs */
    3465              : 
    3466              :     /* Try to get ranges of both inputs */
    3467        81570 :     if (!isgt)
    3468              :     {
    3469        81552 :         if (!get_variable_range(root, &leftvar, lstatop, collation,
    3470              :                                 &leftmin, &leftmax))
    3471        24037 :             goto fail;          /* no range available from stats */
    3472        57515 :         if (!get_variable_range(root, &rightvar, rstatop, collation,
    3473              :                                 &rightmin, &rightmax))
    3474        13405 :             goto fail;          /* no range available from stats */
    3475              :     }
    3476              :     else
    3477              :     {
    3478              :         /* need to swap the max and min */
    3479           18 :         if (!get_variable_range(root, &leftvar, lstatop, collation,
    3480              :                                 &leftmax, &leftmin))
    3481           15 :             goto fail;          /* no range available from stats */
    3482            3 :         if (!get_variable_range(root, &rightvar, rstatop, collation,
    3483              :                                 &rightmax, &rightmin))
    3484            0 :             goto fail;          /* no range available from stats */
    3485              :     }
    3486              : 
    3487              :     /*
    3488              :      * Now, the fraction of the left variable that will be scanned is the
    3489              :      * fraction that's <= the right-side maximum value.  But only believe
    3490              :      * non-default estimates, else stick with our 1.0.
    3491              :      */
    3492        44113 :     selec = scalarineqsel(root, leop, isgt, true, collation, &leftvar,
    3493              :                           rightmax, op_righttype);
    3494        44113 :     if (selec != DEFAULT_INEQ_SEL)
    3495        44110 :         *leftend = selec;
    3496              : 
    3497              :     /* And similarly for the right variable. */
    3498        44113 :     selec = scalarineqsel(root, revleop, isgt, true, collation, &rightvar,
    3499              :                           leftmax, op_lefttype);
    3500        44113 :     if (selec != DEFAULT_INEQ_SEL)
    3501        44113 :         *rightend = selec;
    3502              : 
    3503              :     /*
    3504              :      * Only one of the two "end" fractions can really be less than 1.0;
    3505              :      * believe the smaller estimate and reset the other one to exactly 1.0. If
    3506              :      * we get exactly equal estimates (as can easily happen with self-joins),
    3507              :      * believe neither.
    3508              :      */
    3509        44113 :     if (*leftend > *rightend)
    3510        13617 :         *leftend = 1.0;
    3511        30496 :     else if (*leftend < *rightend)
    3512        17977 :         *rightend = 1.0;
    3513              :     else
    3514        12519 :         *leftend = *rightend = 1.0;
    3515              : 
    3516              :     /*
    3517              :      * Also, the fraction of the left variable that will be scanned before the
    3518              :      * first join pair is found is the fraction that's < the right-side
    3519              :      * minimum value.  But only believe non-default estimates, else stick with
    3520              :      * our own default.
    3521              :      */
    3522        44113 :     selec = scalarineqsel(root, ltop, isgt, false, collation, &leftvar,
    3523              :                           rightmin, op_righttype);
    3524        44113 :     if (selec != DEFAULT_INEQ_SEL)
    3525        44113 :         *leftstart = selec;
    3526              : 
    3527              :     /* And similarly for the right variable. */
    3528        44113 :     selec = scalarineqsel(root, revltop, isgt, false, collation, &rightvar,
    3529              :                           leftmin, op_lefttype);
    3530        44113 :     if (selec != DEFAULT_INEQ_SEL)
    3531        44113 :         *rightstart = selec;
    3532              : 
    3533              :     /*
    3534              :      * Only one of the two "start" fractions can really be more than zero;
    3535              :      * believe the larger estimate and reset the other one to exactly 0.0. If
    3536              :      * we get exactly equal estimates (as can easily happen with self-joins),
    3537              :      * believe neither.
    3538              :      */
    3539        44113 :     if (*leftstart < *rightstart)
    3540        10020 :         *leftstart = 0.0;
    3541        34093 :     else if (*leftstart > *rightstart)
    3542        12624 :         *rightstart = 0.0;
    3543              :     else
    3544        21469 :         *leftstart = *rightstart = 0.0;
    3545              : 
    3546              :     /*
    3547              :      * If the sort order is nulls-first, we're going to have to skip over any
    3548              :      * nulls too.  These would not have been counted by scalarineqsel, and we
    3549              :      * can safely add in this fraction regardless of whether we believe
    3550              :      * scalarineqsel's results or not.  But be sure to clamp the sum to 1.0!
    3551              :      */
    3552        44113 :     if (nulls_first)
    3553              :     {
    3554              :         Form_pg_statistic stats;
    3555              : 
    3556            3 :         if (HeapTupleIsValid(leftvar.statsTuple))
    3557              :         {
    3558            3 :             stats = (Form_pg_statistic) GETSTRUCT(leftvar.statsTuple);
    3559            3 :             *leftstart += stats->stanullfrac;
    3560            3 :             CLAMP_PROBABILITY(*leftstart);
    3561            3 :             *leftend += stats->stanullfrac;
    3562            3 :             CLAMP_PROBABILITY(*leftend);
    3563              :         }
    3564            3 :         if (HeapTupleIsValid(rightvar.statsTuple))
    3565              :         {
    3566            3 :             stats = (Form_pg_statistic) GETSTRUCT(rightvar.statsTuple);
    3567            3 :             *rightstart += stats->stanullfrac;
    3568            3 :             CLAMP_PROBABILITY(*rightstart);
    3569            3 :             *rightend += stats->stanullfrac;
    3570            3 :             CLAMP_PROBABILITY(*rightend);
    3571              :         }
    3572              :     }
    3573              : 
    3574              :     /* Disbelieve start >= end, just in case that can happen */
    3575        44113 :     if (*leftstart >= *leftend)
    3576              :     {
    3577           89 :         *leftstart = 0.0;
    3578           89 :         *leftend = 1.0;
    3579              :     }
    3580        44113 :     if (*rightstart >= *rightend)
    3581              :     {
    3582          752 :         *rightstart = 0.0;
    3583          752 :         *rightend = 1.0;
    3584              :     }
    3585              : 
    3586        43361 : fail:
    3587        81576 :     ReleaseVariableStats(leftvar);
    3588        81576 :     ReleaseVariableStats(rightvar);
    3589              : }
    3590              : 
    3591              : 
    3592              : /*
    3593              :  *  matchingsel -- generic matching-operator selectivity support
    3594              :  *
    3595              :  * Use these for any operators that (a) are on data types for which we collect
    3596              :  * standard statistics, and (b) have behavior for which the default estimate
    3597              :  * (twice DEFAULT_EQ_SEL) is sane.  Typically that is good for match-like
    3598              :  * operators.
    3599              :  */
    3600              : 
    3601              : Datum
    3602          565 : matchingsel(PG_FUNCTION_ARGS)
    3603              : {
    3604          565 :     PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
    3605          565 :     Oid         operator = PG_GETARG_OID(1);
    3606          565 :     List       *args = (List *) PG_GETARG_POINTER(2);
    3607          565 :     int         varRelid = PG_GETARG_INT32(3);
    3608          565 :     Oid         collation = PG_GET_COLLATION();
    3609              :     double      selec;
    3610              : 
    3611              :     /* Use generic restriction selectivity logic. */
    3612          565 :     selec = generic_restriction_selectivity(root, operator, collation,
    3613              :                                             args, varRelid,
    3614              :                                             DEFAULT_MATCHING_SEL);
    3615              : 
    3616          565 :     PG_RETURN_FLOAT8((float8) selec);
    3617              : }
    3618              : 
    3619              : Datum
    3620            3 : matchingjoinsel(PG_FUNCTION_ARGS)
    3621              : {
    3622              :     /* Just punt, for the moment. */
    3623            3 :     PG_RETURN_FLOAT8(DEFAULT_MATCHING_SEL);
    3624              : }
    3625              : 
    3626              : 
    3627              : /*
    3628              :  * Helper routine for estimate_num_groups: add an item to a list of
    3629              :  * GroupVarInfos, but only if it's not known equal to any of the existing
    3630              :  * entries.
    3631              :  */
    3632              : typedef struct
    3633              : {
    3634              :     Node       *var;            /* might be an expression, not just a Var */
    3635              :     RelOptInfo *rel;            /* relation it belongs to */
    3636              :     double      ndistinct;      /* # distinct values */
    3637              :     bool        isdefault;      /* true if DEFAULT_NUM_DISTINCT was used */
    3638              : } GroupVarInfo;
    3639              : 
    3640              : static List *
    3641       232407 : add_unique_group_var(PlannerInfo *root, List *varinfos,
    3642              :                      Node *var, VariableStatData *vardata)
    3643              : {
    3644              :     GroupVarInfo *varinfo;
    3645              :     double      ndistinct;
    3646              :     bool        isdefault;
    3647              :     ListCell   *lc;
    3648              : 
    3649       232407 :     ndistinct = get_variable_numdistinct(vardata, &isdefault);
    3650              : 
    3651              :     /*
    3652              :      * The nullingrels bits within the var could cause the same var to be
    3653              :      * counted multiple times if it's marked with different nullingrels.  They
    3654              :      * could also prevent us from matching the var to the expressions in
    3655              :      * extended statistics (see estimate_multivariate_ndistinct).  So strip
    3656              :      * them out first.
    3657              :      */
    3658       232407 :     var = remove_nulling_relids(var, root->outer_join_rels, NULL);
    3659              : 
    3660       280989 :     foreach(lc, varinfos)
    3661              :     {
    3662        49155 :         varinfo = (GroupVarInfo *) lfirst(lc);
    3663              : 
    3664              :         /* Drop exact duplicates */
    3665        49155 :         if (equal(var, varinfo->var))
    3666          573 :             return varinfos;
    3667              : 
    3668              :         /*
    3669              :          * Drop known-equal vars, but only if they belong to different
    3670              :          * relations (see comments for estimate_num_groups).  We aren't too
    3671              :          * fussy about the semantics of "equal" here.
    3672              :          */
    3673        52255 :         if (vardata->rel != varinfo->rel &&
    3674         3535 :             exprs_known_equal(root, var, varinfo->var, InvalidOid))
    3675              :         {
    3676          150 :             if (varinfo->ndistinct <= ndistinct)
    3677              :             {
    3678              :                 /* Keep older item, forget new one */
    3679          138 :                 return varinfos;
    3680              :             }
    3681              :             else
    3682              :             {
    3683              :                 /* Delete the older item */
    3684           12 :                 varinfos = foreach_delete_current(varinfos, lc);
    3685              :             }
    3686              :         }
    3687              :     }
    3688              : 
    3689       231834 :     varinfo = palloc_object(GroupVarInfo);
    3690              : 
    3691       231834 :     varinfo->var = var;
    3692       231834 :     varinfo->rel = vardata->rel;
    3693       231834 :     varinfo->ndistinct = ndistinct;
    3694       231834 :     varinfo->isdefault = isdefault;
    3695       231834 :     varinfos = lappend(varinfos, varinfo);
    3696       231834 :     return varinfos;
    3697              : }
    3698              : 
    3699              : /*
    3700              :  * estimate_num_groups      - Estimate number of groups in a grouped query
    3701              :  *
    3702              :  * Given a query having a GROUP BY clause, estimate how many groups there
    3703              :  * will be --- ie, the number of distinct combinations of the GROUP BY
    3704              :  * expressions.
    3705              :  *
    3706              :  * This routine is also used to estimate the number of rows emitted by
    3707              :  * a DISTINCT filtering step; that is an isomorphic problem.  (Note:
    3708              :  * actually, we only use it for DISTINCT when there's no grouping or
    3709              :  * aggregation ahead of the DISTINCT.)
    3710              :  *
    3711              :  * Inputs:
    3712              :  *  root - the query
    3713              :  *  groupExprs - list of expressions being grouped by
    3714              :  *  input_rows - number of rows estimated to arrive at the group/unique
    3715              :  *      filter step
    3716              :  *  pgset - NULL, or a List** pointing to a grouping set to filter the
    3717              :  *      groupExprs against
    3718              :  *
    3719              :  * Outputs:
    3720              :  *  estinfo - When passed as non-NULL, the function will set bits in the
    3721              :  *      "flags" field in order to provide callers with additional information
    3722              :  *      about the estimation.  Currently, we only set the SELFLAG_USED_DEFAULT
    3723              :  *      bit if we used any default values in the estimation.
    3724              :  *
    3725              :  * Given the lack of any cross-correlation statistics in the system, it's
    3726              :  * impossible to do anything really trustworthy with GROUP BY conditions
    3727              :  * involving multiple Vars.  We should however avoid assuming the worst
    3728              :  * case (all possible cross-product terms actually appear as groups) since
    3729              :  * very often the grouped-by Vars are highly correlated.  Our current approach
    3730              :  * is as follows:
    3731              :  *  1.  Expressions yielding boolean are assumed to contribute two groups,
    3732              :  *      independently of their content, and are ignored in the subsequent
    3733              :  *      steps.  This is mainly because tests like "col IS NULL" break the
    3734              :  *      heuristic used in step 2 especially badly.
    3735              :  *  2.  Reduce the given expressions to a list of unique Vars used.  For
    3736              :  *      example, GROUP BY a, a + b is treated the same as GROUP BY a, b.
    3737              :  *      It is clearly correct not to count the same Var more than once.
    3738              :  *      It is also reasonable to treat f(x) the same as x: f() cannot
    3739              :  *      increase the number of distinct values (unless it is volatile,
    3740              :  *      which we consider unlikely for grouping), but it probably won't
    3741              :  *      reduce the number of distinct values much either.
    3742              :  *      As a special case, if a GROUP BY expression can be matched to an
    3743              :  *      expressional index for which we have statistics, then we treat the
    3744              :  *      whole expression as though it were just a Var.
    3745              :  *  3.  If the list contains Vars of different relations that are known equal
    3746              :  *      due to equivalence classes, then drop all but one of the Vars from each
    3747              :  *      known-equal set, keeping the one with smallest estimated # of values
    3748              :  *      (since the extra values of the others can't appear in joined rows).
    3749              :  *      Note the reason we only consider Vars of different relations is that
    3750              :  *      if we considered ones of the same rel, we'd be double-counting the
    3751              :  *      restriction selectivity of the equality in the next step.
    3752              :  *  4.  For Vars within a single source rel, we multiply together the numbers
    3753              :  *      of values, clamp to the number of rows in the rel (divided by 10 if
    3754              :  *      more than one Var), and then multiply by a factor based on the
    3755              :  *      selectivity of the restriction clauses for that rel.  When there's
    3756              :  *      more than one Var, the initial product is probably too high (it's the
    3757              :  *      worst case) but clamping to a fraction of the rel's rows seems to be a
    3758              :  *      helpful heuristic for not letting the estimate get out of hand.  (The
    3759              :  *      factor of 10 is derived from pre-Postgres-7.4 practice.)  The factor
    3760              :  *      we multiply by to adjust for the restriction selectivity assumes that
    3761              :  *      the restriction clauses are independent of the grouping, which may not
    3762              :  *      be a valid assumption, but it's hard to do better.
    3763              :  *  5.  If there are Vars from multiple rels, we repeat step 4 for each such
    3764              :  *      rel, and multiply the results together.
    3765              :  * Note that rels not containing grouped Vars are ignored completely, as are
    3766              :  * join clauses.  Such rels cannot increase the number of groups, and we
    3767              :  * assume such clauses do not reduce the number either (somewhat bogus,
    3768              :  * but we don't have the info to do better).
    3769              :  */
    3770              : double
    3771       201306 : estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
    3772              :                     List **pgset, EstimationInfo *estinfo)
    3773              : {
    3774       201306 :     List       *varinfos = NIL;
    3775       201306 :     double      srf_multiplier = 1.0;
    3776              :     double      numdistinct;
    3777              :     ListCell   *l;
    3778              :     int         i;
    3779              : 
    3780              :     /* Zero the estinfo output parameter, if non-NULL */
    3781       201306 :     if (estinfo != NULL)
    3782       175291 :         memset(estinfo, 0, sizeof(EstimationInfo));
    3783              : 
    3784              :     /*
    3785              :      * We don't ever want to return an estimate of zero groups, as that tends
    3786              :      * to lead to division-by-zero and other unpleasantness.  The input_rows
    3787              :      * estimate is usually already at least 1, but clamp it just in case it
    3788              :      * isn't.
    3789              :      */
    3790       201306 :     input_rows = clamp_row_est(input_rows);
    3791              : 
    3792              :     /*
    3793              :      * If no grouping columns, there's exactly one group.  (This can't happen
    3794              :      * for normal cases with GROUP BY or DISTINCT, but it is possible for
    3795              :      * corner cases with set operations.)
    3796              :      */
    3797       201306 :     if (groupExprs == NIL || (pgset && *pgset == NIL))
    3798          581 :         return 1.0;
    3799              : 
    3800              :     /*
    3801              :      * Count groups derived from boolean grouping expressions.  For other
    3802              :      * expressions, find the unique Vars used, treating an expression as a Var
    3803              :      * if we can find stats for it.  For each one, record the statistical
    3804              :      * estimate of number of distinct values (total in its table, without
    3805              :      * regard for filtering).
    3806              :      */
    3807       200725 :     numdistinct = 1.0;
    3808              : 
    3809       200725 :     i = 0;
    3810       432452 :     foreach(l, groupExprs)
    3811              :     {
    3812       231751 :         Node       *groupexpr = (Node *) lfirst(l);
    3813              :         double      this_srf_multiplier;
    3814              :         VariableStatData vardata;
    3815              :         List       *varshere;
    3816              :         ListCell   *l2;
    3817              : 
    3818              :         /* is expression in this grouping set? */
    3819       231751 :         if (pgset && !list_member_int(*pgset, i++))
    3820       192379 :             continue;
    3821              : 
    3822              :         /*
    3823              :          * Set-returning functions in grouping columns are a bit problematic.
    3824              :          * The code below will effectively ignore their SRF nature and come up
    3825              :          * with a numdistinct estimate as though they were scalar functions.
    3826              :          * We compensate by scaling up the end result by the largest SRF
    3827              :          * rowcount estimate.  (This will be an overestimate if the SRF
    3828              :          * produces multiple copies of any output value, but it seems best to
    3829              :          * assume the SRF's outputs are distinct.  In any case, it's probably
    3830              :          * pointless to worry too much about this without much better
    3831              :          * estimates for SRF output rowcounts than we have today.)
    3832              :          */
    3833       231345 :         this_srf_multiplier = expression_returns_set_rows(root, groupexpr);
    3834       231345 :         if (srf_multiplier < this_srf_multiplier)
    3835           78 :             srf_multiplier = this_srf_multiplier;
    3836              : 
    3837              :         /* Short-circuit for expressions returning boolean */
    3838       231345 :         if (exprType(groupexpr) == BOOLOID)
    3839              :         {
    3840          183 :             numdistinct *= 2.0;
    3841          183 :             continue;
    3842              :         }
    3843              : 
    3844              :         /*
    3845              :          * If examine_variable is able to deduce anything about the GROUP BY
    3846              :          * expression, treat it as a single variable even if it's really more
    3847              :          * complicated.
    3848              :          *
    3849              :          * XXX This has the consequence that if there's a statistics object on
    3850              :          * the expression, we don't split it into individual Vars. This
    3851              :          * affects our selection of statistics in
    3852              :          * estimate_multivariate_ndistinct, because it's probably better to
    3853              :          * use more accurate estimate for each expression and treat them as
    3854              :          * independent, than to combine estimates for the extracted variables
    3855              :          * when we don't know how that relates to the expressions.
    3856              :          */
    3857       231162 :         examine_variable(root, groupexpr, 0, &vardata);
    3858       231162 :         if (HeapTupleIsValid(vardata.statsTuple) || vardata.isunique)
    3859              :         {
    3860       191446 :             varinfos = add_unique_group_var(root, varinfos,
    3861              :                                             groupexpr, &vardata);
    3862       191446 :             ReleaseVariableStats(vardata);
    3863       191446 :             continue;
    3864              :         }
    3865        39716 :         ReleaseVariableStats(vardata);
    3866              : 
    3867              :         /*
    3868              :          * Else pull out the component Vars.  Handle PlaceHolderVars by
    3869              :          * recursing into their arguments (effectively assuming that the
    3870              :          * PlaceHolderVar doesn't change the number of groups, which boils
    3871              :          * down to ignoring the possible addition of nulls to the result set).
    3872              :          */
    3873        39716 :         varshere = pull_var_clause(groupexpr,
    3874              :                                    PVC_RECURSE_AGGREGATES |
    3875              :                                    PVC_RECURSE_WINDOWFUNCS |
    3876              :                                    PVC_RECURSE_PLACEHOLDERS);
    3877              : 
    3878              :         /*
    3879              :          * If we find any variable-free GROUP BY item, then either it is a
    3880              :          * constant (and we can ignore it) or it contains a volatile function;
    3881              :          * in the latter case we punt and assume that each input row will
    3882              :          * yield a distinct group.
    3883              :          */
    3884        39716 :         if (varshere == NIL)
    3885              :         {
    3886          368 :             if (contain_volatile_functions(groupexpr))
    3887           24 :                 return input_rows;
    3888          344 :             continue;
    3889              :         }
    3890              : 
    3891              :         /*
    3892              :          * Else add variables to varinfos list
    3893              :          */
    3894        80309 :         foreach(l2, varshere)
    3895              :         {
    3896        40961 :             Node       *var = (Node *) lfirst(l2);
    3897              : 
    3898        40961 :             examine_variable(root, var, 0, &vardata);
    3899        40961 :             varinfos = add_unique_group_var(root, varinfos, var, &vardata);
    3900        40961 :             ReleaseVariableStats(vardata);
    3901              :         }
    3902              :     }
    3903              : 
    3904              :     /*
    3905              :      * If now no Vars, we must have an all-constant or all-boolean GROUP BY
    3906              :      * list.
    3907              :      */
    3908       200701 :     if (varinfos == NIL)
    3909              :     {
    3910              :         /* Apply SRF multiplier as we would do in the long path */
    3911          235 :         numdistinct *= srf_multiplier;
    3912              :         /* Round off */
    3913          235 :         numdistinct = ceil(numdistinct);
    3914              :         /* Guard against out-of-range answers */
    3915          235 :         if (numdistinct > input_rows)
    3916           43 :             numdistinct = input_rows;
    3917          235 :         if (numdistinct < 1.0)
    3918            0 :             numdistinct = 1.0;
    3919          235 :         return numdistinct;
    3920              :     }
    3921              : 
    3922              :     /*
    3923              :      * Group Vars by relation and estimate total numdistinct.
    3924              :      *
    3925              :      * For each iteration of the outer loop, we process the frontmost Var in
    3926              :      * varinfos, plus all other Vars in the same relation.  We remove these
    3927              :      * Vars from the newvarinfos list for the next iteration. This is the
    3928              :      * easiest way to group Vars of same rel together.
    3929              :      */
    3930              :     do
    3931              :     {
    3932       201946 :         GroupVarInfo *varinfo1 = (GroupVarInfo *) linitial(varinfos);
    3933       201946 :         RelOptInfo *rel = varinfo1->rel;
    3934       201946 :         double      reldistinct = 1;
    3935       201946 :         double      relmaxndistinct = reldistinct;
    3936       201946 :         int         relvarcount = 0;
    3937       201946 :         List       *newvarinfos = NIL;
    3938       201946 :         List       *relvarinfos = NIL;
    3939              : 
    3940              :         /*
    3941              :          * Split the list of varinfos in two - one for the current rel, one
    3942              :          * for remaining Vars on other rels.
    3943              :          */
    3944       201946 :         relvarinfos = lappend(relvarinfos, varinfo1);
    3945       234647 :         for_each_from(l, varinfos, 1)
    3946              :         {
    3947        32701 :             GroupVarInfo *varinfo2 = (GroupVarInfo *) lfirst(l);
    3948              : 
    3949        32701 :             if (varinfo2->rel == varinfo1->rel)
    3950              :             {
    3951              :                 /* varinfos on current rel */
    3952        29876 :                 relvarinfos = lappend(relvarinfos, varinfo2);
    3953              :             }
    3954              :             else
    3955              :             {
    3956              :                 /* not time to process varinfo2 yet */
    3957         2825 :                 newvarinfos = lappend(newvarinfos, varinfo2);
    3958              :             }
    3959              :         }
    3960              : 
    3961              :         /*
    3962              :          * Get the numdistinct estimate for the Vars of this rel.  We
    3963              :          * iteratively search for multivariate n-distinct with maximum number
    3964              :          * of vars; assuming that each var group is independent of the others,
    3965              :          * we multiply them together.  Any remaining relvarinfos after no more
    3966              :          * multivariate matches are found are assumed independent too, so
    3967              :          * their individual ndistinct estimates are multiplied also.
    3968              :          *
    3969              :          * While iterating, count how many separate numdistinct values we
    3970              :          * apply.  We apply a fudge factor below, but only if we multiplied
    3971              :          * more than one such values.
    3972              :          */
    3973       403955 :         while (relvarinfos)
    3974              :         {
    3975              :             double      mvndistinct;
    3976              : 
    3977       202009 :             if (estimate_multivariate_ndistinct(root, rel, &relvarinfos,
    3978              :                                                 &mvndistinct))
    3979              :             {
    3980          207 :                 reldistinct *= mvndistinct;
    3981          207 :                 if (relmaxndistinct < mvndistinct)
    3982          201 :                     relmaxndistinct = mvndistinct;
    3983          207 :                 relvarcount++;
    3984              :             }
    3985              :             else
    3986              :             {
    3987       433186 :                 foreach(l, relvarinfos)
    3988              :                 {
    3989       231384 :                     GroupVarInfo *varinfo2 = (GroupVarInfo *) lfirst(l);
    3990              : 
    3991       231384 :                     reldistinct *= varinfo2->ndistinct;
    3992       231384 :                     if (relmaxndistinct < varinfo2->ndistinct)
    3993       205562 :                         relmaxndistinct = varinfo2->ndistinct;
    3994       231384 :                     relvarcount++;
    3995              : 
    3996              :                     /*
    3997              :                      * When varinfo2's isdefault is set then we'd better set
    3998              :                      * the SELFLAG_USED_DEFAULT bit in the EstimationInfo.
    3999              :                      */
    4000       231384 :                     if (estinfo != NULL && varinfo2->isdefault)
    4001         9782 :                         estinfo->flags |= SELFLAG_USED_DEFAULT;
    4002              :                 }
    4003              : 
    4004              :                 /* we're done with this relation */
    4005       201802 :                 relvarinfos = NIL;
    4006              :             }
    4007              :         }
    4008              : 
    4009              :         /*
    4010              :          * Sanity check --- don't divide by zero if empty relation.
    4011              :          */
    4012              :         Assert(IS_SIMPLE_REL(rel));
    4013       201946 :         if (rel->tuples > 0)
    4014              :         {
    4015              :             /*
    4016              :              * Clamp to size of rel, or size of rel / 10 if multiple Vars. The
    4017              :              * fudge factor is because the Vars are probably correlated but we
    4018              :              * don't know by how much.  We should never clamp to less than the
    4019              :              * largest ndistinct value for any of the Vars, though, since
    4020              :              * there will surely be at least that many groups.
    4021              :              */
    4022       201419 :             double      clamp = rel->tuples;
    4023              : 
    4024       201419 :             if (relvarcount > 1)
    4025              :             {
    4026        27151 :                 clamp *= 0.1;
    4027        27151 :                 if (clamp < relmaxndistinct)
    4028              :                 {
    4029        25812 :                     clamp = relmaxndistinct;
    4030              :                     /* for sanity in case some ndistinct is too large: */
    4031        25812 :                     if (clamp > rel->tuples)
    4032           39 :                         clamp = rel->tuples;
    4033              :                 }
    4034              :             }
    4035       201419 :             if (reldistinct > clamp)
    4036        22015 :                 reldistinct = clamp;
    4037              : 
    4038              :             /*
    4039              :              * Update the estimate based on the restriction selectivity,
    4040              :              * guarding against division by zero when reldistinct is zero.
    4041              :              * Also skip this if we know that we are returning all rows.
    4042              :              */
    4043       201419 :             if (reldistinct > 0 && rel->rows < rel->tuples)
    4044              :             {
    4045              :                 /*
    4046              :                  * Given a table containing N rows with n distinct values in a
    4047              :                  * uniform distribution, if we select p rows at random then
    4048              :                  * the expected number of distinct values selected is
    4049              :                  *
    4050              :                  * n * (1 - product((N-N/n-i)/(N-i), i=0..p-1))
    4051              :                  *
    4052              :                  * = n * (1 - (N-N/n)! / (N-N/n-p)! * (N-p)! / N!)
    4053              :                  *
    4054              :                  * See "Approximating block accesses in database
    4055              :                  * organizations", S. B. Yao, Communications of the ACM,
    4056              :                  * Volume 20 Issue 4, April 1977 Pages 260-261.
    4057              :                  *
    4058              :                  * Alternatively, re-arranging the terms from the factorials,
    4059              :                  * this may be written as
    4060              :                  *
    4061              :                  * n * (1 - product((N-p-i)/(N-i), i=0..N/n-1))
    4062              :                  *
    4063              :                  * This form of the formula is more efficient to compute in
    4064              :                  * the common case where p is larger than N/n.  Additionally,
    4065              :                  * as pointed out by Dell'Era, if i << N for all terms in the
    4066              :                  * product, it can be approximated by
    4067              :                  *
    4068              :                  * n * (1 - ((N-p)/N)^(N/n))
    4069              :                  *
    4070              :                  * See "Expected distinct values when selecting from a bag
    4071              :                  * without replacement", Alberto Dell'Era,
    4072              :                  * http://www.adellera.it/investigations/distinct_balls/.
    4073              :                  *
    4074              :                  * The condition i << N is equivalent to n >> 1, so this is a
    4075              :                  * good approximation when the number of distinct values in
    4076              :                  * the table is large.  It turns out that this formula also
    4077              :                  * works well even when n is small.
    4078              :                  */
    4079        66325 :                 reldistinct *=
    4080        66325 :                     (1 - pow((rel->tuples - rel->rows) / rel->tuples,
    4081        66325 :                              rel->tuples / reldistinct));
    4082              :             }
    4083       201419 :             reldistinct = clamp_row_est(reldistinct);
    4084              : 
    4085              :             /*
    4086              :              * Update estimate of total distinct groups.
    4087              :              */
    4088       201419 :             numdistinct *= reldistinct;
    4089              :         }
    4090              : 
    4091       201946 :         varinfos = newvarinfos;
    4092       201946 :     } while (varinfos != NIL);
    4093              : 
    4094              :     /* Now we can account for the effects of any SRFs */
    4095       200466 :     numdistinct *= srf_multiplier;
    4096              : 
    4097              :     /* Round off */
    4098       200466 :     numdistinct = ceil(numdistinct);
    4099              : 
    4100              :     /* Guard against out-of-range answers */
    4101       200466 :     if (numdistinct > input_rows)
    4102        42308 :         numdistinct = input_rows;
    4103       200466 :     if (numdistinct < 1.0)
    4104            0 :         numdistinct = 1.0;
    4105              : 
    4106       200466 :     return numdistinct;
    4107              : }
    4108              : 
    4109              : /*
    4110              :  * Try to estimate the bucket size of the hash join inner side when the join
    4111              :  * condition contains two or more clauses by employing extended statistics.
    4112              :  *
    4113              :  * The main idea of this approach is that the distinct value generated by
    4114              :  * multivariate estimation on two or more columns would provide less bucket size
    4115              :  * than estimation on one separate column.
    4116              :  *
    4117              :  * IMPORTANT: It is crucial to synchronize the approach of combining different
    4118              :  * estimations with the caller's method.
    4119              :  *
    4120              :  * Return a list of clauses that didn't fetch any extended statistics.
    4121              :  */
    4122              : List *
    4123       250175 : estimate_multivariate_bucketsize(PlannerInfo *root, RelOptInfo *inner,
    4124              :                                  List *hashclauses,
    4125              :                                  Selectivity *innerbucketsize)
    4126              : {
    4127              :     List       *clauses;
    4128              :     List       *otherclauses;
    4129              :     double      ndistinct;
    4130              : 
    4131       250175 :     if (list_length(hashclauses) <= 1)
    4132              :     {
    4133              :         /*
    4134              :          * Nothing to do for a single clause.  Could we employ univariate
    4135              :          * extended stat here?
    4136              :          */
    4137       229955 :         return hashclauses;
    4138              :     }
    4139              : 
    4140              :     /* "clauses" is the list of hashclauses we've not dealt with yet */
    4141        20220 :     clauses = list_copy(hashclauses);
    4142              :     /* "otherclauses" holds clauses we are going to return to caller */
    4143        20220 :     otherclauses = NIL;
    4144              :     /* current estimate of ndistinct */
    4145        20220 :     ndistinct = 1.0;
    4146        40446 :     while (clauses != NIL)
    4147              :     {
    4148              :         ListCell   *lc;
    4149        20226 :         int         relid = -1;
    4150        20226 :         List       *varinfos = NIL;
    4151        20226 :         List       *origin_rinfos = NIL;
    4152              :         double      mvndistinct;
    4153              :         List       *origin_varinfos;
    4154        20226 :         int         group_relid = -1;
    4155        20226 :         RelOptInfo *group_rel = NULL;
    4156              :         ListCell   *lc1,
    4157              :                    *lc2;
    4158              : 
    4159              :         /*
    4160              :          * Find clauses, referencing the same single base relation and try to
    4161              :          * estimate such a group with extended statistics.  Create varinfo for
    4162              :          * an approved clause, push it to otherclauses, if it can't be
    4163              :          * estimated here or ignore to process at the next iteration.
    4164              :          */
    4165        60984 :         foreach(lc, clauses)
    4166              :         {
    4167        40758 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
    4168              :             Node       *expr;
    4169              :             Relids      relids;
    4170              :             GroupVarInfo *varinfo;
    4171              : 
    4172              :             /*
    4173              :              * Find the inner side of the join, which we need to estimate the
    4174              :              * number of buckets.  Use outer_is_left because the
    4175              :              * clause_sides_match_join routine has called on hash clauses.
    4176              :              */
    4177        81516 :             relids = rinfo->outer_is_left ?
    4178        40758 :                 rinfo->right_relids : rinfo->left_relids;
    4179        81516 :             expr = rinfo->outer_is_left ?
    4180        40758 :                 get_rightop(rinfo->clause) : get_leftop(rinfo->clause);
    4181              : 
    4182        40758 :             if (bms_get_singleton_member(relids, &relid) &&
    4183        39143 :                 root->simple_rel_array[relid]->statlist != NIL)
    4184           24 :             {
    4185           30 :                 bool        is_duplicate = false;
    4186              : 
    4187              :                 /*
    4188              :                  * This inner-side expression references only one relation.
    4189              :                  * Extended statistics on this clause can exist.
    4190              :                  */
    4191           30 :                 if (group_relid < 0)
    4192              :                 {
    4193           15 :                     RangeTblEntry *rte = root->simple_rte_array[relid];
    4194              : 
    4195           15 :                     if (!rte || (rte->relkind != RELKIND_RELATION &&
    4196            0 :                                  rte->relkind != RELKIND_MATVIEW &&
    4197            0 :                                  rte->relkind != RELKIND_FOREIGN_TABLE &&
    4198            0 :                                  rte->relkind != RELKIND_PARTITIONED_TABLE))
    4199              :                     {
    4200              :                         /* Extended statistics can't exist in principle */
    4201            0 :                         otherclauses = lappend(otherclauses, rinfo);
    4202            0 :                         clauses = foreach_delete_current(clauses, lc);
    4203            0 :                         continue;
    4204              :                     }
    4205              : 
    4206           15 :                     group_relid = relid;
    4207           15 :                     group_rel = root->simple_rel_array[relid];
    4208              :                 }
    4209           15 :                 else if (group_relid != relid)
    4210              :                 {
    4211              :                     /*
    4212              :                      * Being in the group forming state we don't need other
    4213              :                      * clauses.
    4214              :                      */
    4215            0 :                     continue;
    4216              :                 }
    4217              : 
    4218              :                 /*
    4219              :                  * We're going to add the new clause to the varinfos list.  We
    4220              :                  * might re-use add_unique_group_var(), but we don't do so for
    4221              :                  * two reasons.
    4222              :                  *
    4223              :                  * 1) We must keep the origin_rinfos list ordered exactly the
    4224              :                  * same way as varinfos.
    4225              :                  *
    4226              :                  * 2) add_unique_group_var() is designed for
    4227              :                  * estimate_num_groups(), where a larger number of groups is
    4228              :                  * worse.   While estimating the number of hash buckets, we
    4229              :                  * have the opposite: a lesser number of groups is worse.
    4230              :                  * Therefore, we don't have to remove "known equal" vars: the
    4231              :                  * removed var may valuably contribute to the multivariate
    4232              :                  * statistics to grow the number of groups.
    4233              :                  */
    4234              : 
    4235              :                 /*
    4236              :                  * Clear nullingrels to correctly match hash keys.  See
    4237              :                  * add_unique_group_var()'s comment for details.
    4238              :                  */
    4239           30 :                 expr = remove_nulling_relids(expr, root->outer_join_rels, NULL);
    4240              : 
    4241              :                 /*
    4242              :                  * Detect and exclude exact duplicates from the list of hash
    4243              :                  * keys (like add_unique_group_var does).
    4244              :                  */
    4245           42 :                 foreach(lc1, varinfos)
    4246              :                 {
    4247           18 :                     varinfo = (GroupVarInfo *) lfirst(lc1);
    4248              : 
    4249           18 :                     if (!equal(expr, varinfo->var))
    4250           12 :                         continue;
    4251              : 
    4252            6 :                     is_duplicate = true;
    4253            6 :                     break;
    4254              :                 }
    4255              : 
    4256           30 :                 if (is_duplicate)
    4257              :                 {
    4258              :                     /*
    4259              :                      * Skip exact duplicates. Adding them to the otherclauses
    4260              :                      * list also doesn't make sense.
    4261              :                      */
    4262            6 :                     continue;
    4263              :                 }
    4264              : 
    4265              :                 /*
    4266              :                  * Initialize GroupVarInfo.  We only use it to call
    4267              :                  * estimate_multivariate_ndistinct(), which doesn't care about
    4268              :                  * ndistinct and isdefault fields.  Thus, skip these fields.
    4269              :                  */
    4270           24 :                 varinfo = palloc0_object(GroupVarInfo);
    4271           24 :                 varinfo->var = expr;
    4272           24 :                 varinfo->rel = root->simple_rel_array[relid];
    4273           24 :                 varinfos = lappend(varinfos, varinfo);
    4274              : 
    4275              :                 /*
    4276              :                  * Remember the link to RestrictInfo for the case the clause
    4277              :                  * is failed to be estimated.
    4278              :                  */
    4279           24 :                 origin_rinfos = lappend(origin_rinfos, rinfo);
    4280              :             }
    4281              :             else
    4282              :             {
    4283              :                 /* This clause can't be estimated with extended statistics */
    4284        40728 :                 otherclauses = lappend(otherclauses, rinfo);
    4285              :             }
    4286              : 
    4287        40752 :             clauses = foreach_delete_current(clauses, lc);
    4288              :         }
    4289              : 
    4290        20226 :         if (list_length(varinfos) < 2)
    4291              :         {
    4292              :             /*
    4293              :              * Multivariate statistics doesn't apply to single columns except
    4294              :              * for expressions, but it has not been implemented yet.
    4295              :              */
    4296        20220 :             otherclauses = list_concat(otherclauses, origin_rinfos);
    4297        20220 :             list_free_deep(varinfos);
    4298        20220 :             list_free(origin_rinfos);
    4299        20220 :             continue;
    4300              :         }
    4301              : 
    4302              :         Assert(group_rel != NULL);
    4303              : 
    4304              :         /* Employ the extended statistics. */
    4305            6 :         origin_varinfos = varinfos;
    4306              :         for (;;)
    4307            6 :         {
    4308           12 :             bool        estimated = estimate_multivariate_ndistinct(root,
    4309              :                                                                     group_rel,
    4310              :                                                                     &varinfos,
    4311              :                                                                     &mvndistinct);
    4312              : 
    4313           12 :             if (!estimated)
    4314            6 :                 break;
    4315              : 
    4316              :             /*
    4317              :              * We've got an estimation.  Use ndistinct value in a consistent
    4318              :              * way - according to the caller's logic (see
    4319              :              * final_cost_hashjoin).
    4320              :              */
    4321            6 :             if (ndistinct < mvndistinct)
    4322            6 :                 ndistinct = mvndistinct;
    4323              :             Assert(ndistinct >= 1.0);
    4324              :         }
    4325              : 
    4326              :         Assert(list_length(origin_varinfos) == list_length(origin_rinfos));
    4327              : 
    4328              :         /* Collect unmatched clauses as otherclauses. */
    4329           21 :         forboth(lc1, origin_varinfos, lc2, origin_rinfos)
    4330              :         {
    4331           15 :             GroupVarInfo *vinfo = lfirst(lc1);
    4332              : 
    4333           15 :             if (!list_member_ptr(varinfos, vinfo))
    4334              :                 /* Already estimated */
    4335           15 :                 continue;
    4336              : 
    4337              :             /* Can't be estimated here - push to the returning list */
    4338            0 :             otherclauses = lappend(otherclauses, lfirst(lc2));
    4339              :         }
    4340              :     }
    4341              : 
    4342        20220 :     *innerbucketsize = 1.0 / ndistinct;
    4343        20220 :     return otherclauses;
    4344              : }
    4345              : 
    4346              : /*
    4347              :  * Estimate hash bucket statistics when the specified expression is used
    4348              :  * as a hash key for the given number of buckets.
    4349              :  *
    4350              :  * This attempts to determine two values:
    4351              :  *
    4352              :  * 1. The frequency of the most common value of the expression (returns
    4353              :  * zero into *mcv_freq if we can't get that).  This will be frequency
    4354              :  * relative to the entire underlying table.
    4355              :  *
    4356              :  * 2. The "bucketsize fraction", ie, average number of entries in a bucket
    4357              :  * divided by total number of tuples to be hashed.
    4358              :  *
    4359              :  * XXX This is really pretty bogus since we're effectively assuming that the
    4360              :  * distribution of hash keys will be the same after applying restriction
    4361              :  * clauses as it was in the underlying relation.  However, we are not nearly
    4362              :  * smart enough to figure out how the restrict clauses might change the
    4363              :  * distribution, so this will have to do for now.
    4364              :  *
    4365              :  * We are passed the number of buckets the executor will use for the given
    4366              :  * input relation.  If the data were perfectly distributed, with the same
    4367              :  * number of tuples going into each available bucket, then the bucketsize
    4368              :  * fraction would be 1/nbuckets.  But this happy state of affairs will occur
    4369              :  * only if (a) there are at least nbuckets distinct data values, and (b)
    4370              :  * we have a not-too-skewed data distribution.  Otherwise the buckets will
    4371              :  * be nonuniformly occupied.  If the other relation in the join has a key
    4372              :  * distribution similar to this one's, then the most-loaded buckets are
    4373              :  * exactly those that will be probed most often.  Therefore, the "average"
    4374              :  * bucket size for costing purposes should really be taken as something close
    4375              :  * to the "worst case" bucket size.  We try to estimate this by adjusting the
    4376              :  * fraction if there are too few distinct data values, and then clamping to
    4377              :  * at least the bucket size implied by the most common value's frequency.
    4378              :  *
    4379              :  * If no statistics are available, use a default estimate of 0.1.  This will
    4380              :  * discourage use of a hash rather strongly if the inner relation is large,
    4381              :  * which is what we want.  We do not want to hash unless we know that the
    4382              :  * inner rel is well-dispersed (or the alternatives seem much worse).
    4383              :  *
    4384              :  * The caller should also check that the mcv_freq is not so large that the
    4385              :  * most common value would by itself require an impractically large bucket.
    4386              :  * In a hash join, the executor can split buckets if they get too big, but
    4387              :  * obviously that doesn't help for a bucket that contains many duplicates of
    4388              :  * the same value.
    4389              :  */
    4390              : void
    4391       114503 : estimate_hash_bucket_stats(PlannerInfo *root, Node *hashkey, double nbuckets,
    4392              :                            Selectivity *mcv_freq,
    4393              :                            Selectivity *bucketsize_frac)
    4394              : {
    4395              :     VariableStatData vardata;
    4396              :     double      estfract,
    4397              :                 ndistinct;
    4398              :     bool        isdefault;
    4399              :     AttStatsSlot sslot;
    4400              : 
    4401       114503 :     examine_variable(root, hashkey, 0, &vardata);
    4402              : 
    4403              :     /* Initialize *mcv_freq to "unknown" */
    4404       114503 :     *mcv_freq = 0.0;
    4405              : 
    4406              :     /* Look up the frequency of the most common value, if available */
    4407       114503 :     if (HeapTupleIsValid(vardata.statsTuple))
    4408              :     {
    4409        77743 :         if (get_attstatsslot(&sslot, vardata.statsTuple,
    4410              :                              STATISTIC_KIND_MCV, InvalidOid,
    4411              :                              ATTSTATSSLOT_NUMBERS))
    4412              :         {
    4413              :             /*
    4414              :              * The first MCV stat is for the most common value.
    4415              :              */
    4416        44355 :             if (sslot.nnumbers > 0)
    4417        44355 :                 *mcv_freq = sslot.numbers[0];
    4418        44355 :             free_attstatsslot(&sslot);
    4419              :         }
    4420        33388 :         else if (get_attstatsslot(&sslot, vardata.statsTuple,
    4421              :                                   STATISTIC_KIND_HISTOGRAM, InvalidOid,
    4422              :                                   0))
    4423              :         {
    4424              :             /*
    4425              :              * If there are no recorded MCVs, but we do have a histogram, then
    4426              :              * assume that ANALYZE determined that the column is unique.
    4427              :              */
    4428        32056 :             if (vardata.rel && vardata.rel->tuples > 0)
    4429        32047 :                 *mcv_freq = 1.0 / vardata.rel->tuples;
    4430              :         }
    4431              :     }
    4432              : 
    4433              :     /* Get number of distinct values */
    4434       114503 :     ndistinct = get_variable_numdistinct(&vardata, &isdefault);
    4435              : 
    4436              :     /*
    4437              :      * If ndistinct isn't real, punt.  We normally return 0.1, but if the
    4438              :      * mcv_freq is known to be even higher than that, use it instead.
    4439              :      */
    4440       114503 :     if (isdefault)
    4441              :     {
    4442        16913 :         *bucketsize_frac = (Selectivity) Max(0.1, *mcv_freq);
    4443        16913 :         ReleaseVariableStats(vardata);
    4444        16913 :         return;
    4445              :     }
    4446              : 
    4447              :     /*
    4448              :      * Adjust ndistinct to account for restriction clauses.  Observe we are
    4449              :      * assuming that the data distribution is affected uniformly by the
    4450              :      * restriction clauses!
    4451              :      *
    4452              :      * XXX Possibly better way, but much more expensive: multiply by
    4453              :      * selectivity of rel's restriction clauses that mention the target Var.
    4454              :      */
    4455        97590 :     if (vardata.rel && vardata.rel->tuples > 0)
    4456              :     {
    4457        97567 :         ndistinct *= vardata.rel->rows / vardata.rel->tuples;
    4458        97567 :         ndistinct = clamp_row_est(ndistinct);
    4459              :     }
    4460              : 
    4461              :     /*
    4462              :      * Initial estimate of bucketsize fraction is 1/nbuckets as long as the
    4463              :      * number of buckets is less than the expected number of distinct values;
    4464              :      * otherwise it is 1/ndistinct.
    4465              :      */
    4466        97590 :     if (ndistinct > nbuckets)
    4467           38 :         estfract = 1.0 / nbuckets;
    4468              :     else
    4469        97552 :         estfract = 1.0 / ndistinct;
    4470              : 
    4471              :     /*
    4472              :      * Clamp the bucketsize fraction to be not less than the MCV frequency,
    4473              :      * since whichever bucket the MCV values end up in will have at least that
    4474              :      * size.  This has no effect if *mcv_freq is still zero.
    4475              :      */
    4476        97590 :     estfract = Max(estfract, *mcv_freq);
    4477              : 
    4478        97590 :     *bucketsize_frac = (Selectivity) estfract;
    4479              : 
    4480        97590 :     ReleaseVariableStats(vardata);
    4481              : }
    4482              : 
    4483              : /*
    4484              :  * estimate_hashagg_tablesize
    4485              :  *    estimate the number of bytes that a hash aggregate hashtable will
    4486              :  *    require based on the agg_costs, path width and number of groups.
    4487              :  *
    4488              :  * We return the result as "double" to forestall any possible overflow
    4489              :  * problem in the multiplication by dNumGroups.
    4490              :  *
    4491              :  * XXX this may be over-estimating the size now that hashagg knows to omit
    4492              :  * unneeded columns from the hashtable.  Also for mixed-mode grouping sets,
    4493              :  * grouping columns not in the hashed set are counted here even though hashagg
    4494              :  * won't store them.  Is this a problem?
    4495              :  */
    4496              : double
    4497         1311 : estimate_hashagg_tablesize(PlannerInfo *root, Path *path,
    4498              :                            const AggClauseCosts *agg_costs, double dNumGroups)
    4499              : {
    4500              :     Size        hashentrysize;
    4501              : 
    4502         1311 :     hashentrysize = hash_agg_entry_size(list_length(root->aggtransinfos),
    4503         1311 :                                         path->pathtarget->width,
    4504         1311 :                                         agg_costs->transitionSpace);
    4505              : 
    4506              :     /*
    4507              :      * Note that this disregards the effect of fill-factor and growth policy
    4508              :      * of the hash table.  That's probably ok, given that the default
    4509              :      * fill-factor is relatively high.  It'd be hard to meaningfully factor in
    4510              :      * "double-in-size" growth policies here.
    4511              :      */
    4512         1311 :     return hashentrysize * dNumGroups;
    4513              : }
    4514              : 
    4515              : 
    4516              : /*-------------------------------------------------------------------------
    4517              :  *
    4518              :  * Support routines
    4519              :  *
    4520              :  *-------------------------------------------------------------------------
    4521              :  */
    4522              : 
    4523              : /*
    4524              :  * Find the best matching ndistinct extended statistics for the given list of
    4525              :  * GroupVarInfos.
    4526              :  *
    4527              :  * Callers must ensure that the given GroupVarInfos all belong to 'rel' and
    4528              :  * the GroupVarInfos list does not contain any duplicate Vars or expressions.
    4529              :  *
    4530              :  * When statistics are found that match > 1 of the given GroupVarInfo, the
    4531              :  * *ndistinct parameter is set according to the ndistinct estimate and a new
    4532              :  * list is built with the matching GroupVarInfos removed, which is output via
    4533              :  * the *varinfos parameter before returning true.  When no matching stats are
    4534              :  * found, false is returned and the *varinfos and *ndistinct parameters are
    4535              :  * left untouched.
    4536              :  */
    4537              : static bool
    4538       202021 : estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
    4539              :                                 List **varinfos, double *ndistinct)
    4540              : {
    4541              :     ListCell   *lc;
    4542              :     int         nmatches_vars;
    4543              :     int         nmatches_exprs;
    4544       202021 :     Oid         statOid = InvalidOid;
    4545              :     MVNDistinct *stats;
    4546       202021 :     StatisticExtInfo *matched_info = NULL;
    4547       202021 :     RangeTblEntry *rte = planner_rt_fetch(rel->relid, root);
    4548              : 
    4549              :     /* bail out immediately if the table has no extended statistics */
    4550       202021 :     if (!rel->statlist)
    4551       201738 :         return false;
    4552              : 
    4553              :     /* look for the ndistinct statistics object matching the most vars */
    4554          283 :     nmatches_vars = 0;          /* we require at least two matches */
    4555          283 :     nmatches_exprs = 0;
    4556         1127 :     foreach(lc, rel->statlist)
    4557              :     {
    4558              :         ListCell   *lc2;
    4559          844 :         StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc);
    4560          844 :         int         nshared_vars = 0;
    4561          844 :         int         nshared_exprs = 0;
    4562              : 
    4563              :         /* skip statistics of other kinds */
    4564          844 :         if (info->kind != STATS_EXT_NDISTINCT)
    4565          399 :             continue;
    4566              : 
    4567              :         /* skip statistics with mismatching stxdinherit value */
    4568          445 :         if (info->inherit != rte->inh)
    4569           15 :             continue;
    4570              : 
    4571              :         /*
    4572              :          * Determine how many expressions (and variables in non-matched
    4573              :          * expressions) match. We'll then use these numbers to pick the
    4574              :          * statistics object that best matches the clauses.
    4575              :          */
    4576         1361 :         foreach(lc2, *varinfos)
    4577              :         {
    4578              :             ListCell   *lc3;
    4579          931 :             GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc2);
    4580              :             AttrNumber  attnum;
    4581              : 
    4582              :             Assert(varinfo->rel == rel);
    4583              : 
    4584              :             /* simple Var, search in statistics keys directly */
    4585          931 :             if (IsA(varinfo->var, Var))
    4586              :             {
    4587          748 :                 attnum = ((Var *) varinfo->var)->varattno;
    4588              : 
    4589              :                 /*
    4590              :                  * Ignore system attributes - we don't support statistics on
    4591              :                  * them, so can't match them (and it'd fail as the values are
    4592              :                  * negative).
    4593              :                  */
    4594          748 :                 if (!AttrNumberIsForUserDefinedAttr(attnum))
    4595            6 :                     continue;
    4596              : 
    4597          742 :                 if (bms_is_member(attnum, info->keys))
    4598          438 :                     nshared_vars++;
    4599              : 
    4600          742 :                 continue;
    4601              :             }
    4602              : 
    4603              :             /* expression - see if it's in the statistics object */
    4604          330 :             foreach(lc3, info->exprs)
    4605              :             {
    4606          264 :                 Node       *expr = (Node *) lfirst(lc3);
    4607              : 
    4608          264 :                 if (equal(varinfo->var, expr))
    4609              :                 {
    4610          117 :                     nshared_exprs++;
    4611          117 :                     break;
    4612              :                 }
    4613              :             }
    4614              :         }
    4615              : 
    4616              :         /*
    4617              :          * The ndistinct extended statistics contain estimates for a minimum
    4618              :          * of pairs of columns which the statistics are defined on and
    4619              :          * certainly not single columns.  Here we skip unless we managed to
    4620              :          * match to at least two columns.
    4621              :          */
    4622          430 :         if (nshared_vars + nshared_exprs < 2)
    4623          199 :             continue;
    4624              : 
    4625              :         /*
    4626              :          * Check if these statistics are a better match than the previous best
    4627              :          * match and if so, take note of the StatisticExtInfo.
    4628              :          *
    4629              :          * The statslist is sorted by statOid, so the StatisticExtInfo we
    4630              :          * select as the best match is deterministic even when multiple sets
    4631              :          * of statistics match equally as well.
    4632              :          */
    4633          231 :         if ((nshared_exprs > nmatches_exprs) ||
    4634          177 :             (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars)))
    4635              :         {
    4636          219 :             statOid = info->statOid;
    4637          219 :             nmatches_vars = nshared_vars;
    4638          219 :             nmatches_exprs = nshared_exprs;
    4639          219 :             matched_info = info;
    4640              :         }
    4641              :     }
    4642              : 
    4643              :     /* No match? */
    4644          283 :     if (statOid == InvalidOid)
    4645           70 :         return false;
    4646              : 
    4647              :     Assert(nmatches_vars + nmatches_exprs > 1);
    4648              : 
    4649          213 :     stats = statext_ndistinct_load(statOid, rte->inh);
    4650              : 
    4651              :     /*
    4652              :      * If we have a match, search it for the specific item that matches (there
    4653              :      * must be one), and construct the output values.
    4654              :      */
    4655          213 :     if (stats)
    4656              :     {
    4657              :         int         i;
    4658          213 :         List       *newlist = NIL;
    4659          213 :         MVNDistinctItem *item = NULL;
    4660              :         ListCell   *lc2;
    4661          213 :         Bitmapset  *matched = NULL;
    4662              :         AttrNumber  attnum_offset;
    4663              : 
    4664              :         /*
    4665              :          * How much we need to offset the attnums? If there are no
    4666              :          * expressions, no offset is needed. Otherwise offset enough to move
    4667              :          * the lowest one (which is equal to number of expressions) to 1.
    4668              :          */
    4669          213 :         if (matched_info->exprs)
    4670           75 :             attnum_offset = (list_length(matched_info->exprs) + 1);
    4671              :         else
    4672          138 :             attnum_offset = 0;
    4673              : 
    4674              :         /* see what actually matched */
    4675          744 :         foreach(lc2, *varinfos)
    4676              :         {
    4677              :             ListCell   *lc3;
    4678              :             int         idx;
    4679          531 :             bool        found = false;
    4680              : 
    4681          531 :             GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc2);
    4682              : 
    4683              :             /*
    4684              :              * Process a simple Var expression, by matching it to keys
    4685              :              * directly. If there's a matching expression, we'll try matching
    4686              :              * it later.
    4687              :              */
    4688          531 :             if (IsA(varinfo->var, Var))
    4689              :             {
    4690          438 :                 AttrNumber  attnum = ((Var *) varinfo->var)->varattno;
    4691              : 
    4692              :                 /*
    4693              :                  * Ignore expressions on system attributes. Can't rely on the
    4694              :                  * bms check for negative values.
    4695              :                  */
    4696          438 :                 if (!AttrNumberIsForUserDefinedAttr(attnum))
    4697            3 :                     continue;
    4698              : 
    4699              :                 /* Is the variable covered by the statistics object? */
    4700          435 :                 if (!bms_is_member(attnum, matched_info->keys))
    4701           60 :                     continue;
    4702              : 
    4703          375 :                 attnum = attnum + attnum_offset;
    4704              : 
    4705              :                 /* ensure sufficient offset */
    4706              :                 Assert(AttrNumberIsForUserDefinedAttr(attnum));
    4707              : 
    4708          375 :                 matched = bms_add_member(matched, attnum);
    4709              : 
    4710          375 :                 found = true;
    4711              :             }
    4712              : 
    4713              :             /*
    4714              :              * XXX Maybe we should allow searching the expressions even if we
    4715              :              * found an attribute matching the expression? That would handle
    4716              :              * trivial expressions like "(a)" but it seems fairly useless.
    4717              :              */
    4718          468 :             if (found)
    4719          375 :                 continue;
    4720              : 
    4721              :             /* expression - see if it's in the statistics object */
    4722           93 :             idx = 0;
    4723          153 :             foreach(lc3, matched_info->exprs)
    4724              :             {
    4725          138 :                 Node       *expr = (Node *) lfirst(lc3);
    4726              : 
    4727          138 :                 if (equal(varinfo->var, expr))
    4728              :                 {
    4729           78 :                     AttrNumber  attnum = -(idx + 1);
    4730              : 
    4731           78 :                     attnum = attnum + attnum_offset;
    4732              : 
    4733              :                     /* ensure sufficient offset */
    4734              :                     Assert(AttrNumberIsForUserDefinedAttr(attnum));
    4735              : 
    4736           78 :                     matched = bms_add_member(matched, attnum);
    4737              : 
    4738              :                     /* there should be just one matching expression */
    4739           78 :                     break;
    4740              :                 }
    4741              : 
    4742           60 :                 idx++;
    4743              :             }
    4744              :         }
    4745              : 
    4746              :         /* Find the specific item that exactly matches the combination */
    4747          432 :         for (i = 0; i < stats->nitems; i++)
    4748              :         {
    4749              :             int         j;
    4750          432 :             MVNDistinctItem *tmpitem = &stats->items[i];
    4751              : 
    4752          432 :             if (tmpitem->nattributes != bms_num_members(matched))
    4753           81 :                 continue;
    4754              : 
    4755              :             /* assume it's the right item */
    4756          351 :             item = tmpitem;
    4757              : 
    4758              :             /* check that all item attributes/expressions fit the match */
    4759          846 :             for (j = 0; j < tmpitem->nattributes; j++)
    4760              :             {
    4761          633 :                 AttrNumber  attnum = tmpitem->attributes[j];
    4762              : 
    4763              :                 /*
    4764              :                  * Thanks to how we constructed the matched bitmap above, we
    4765              :                  * can just offset all attnums the same way.
    4766              :                  */
    4767          633 :                 attnum = attnum + attnum_offset;
    4768              : 
    4769          633 :                 if (!bms_is_member(attnum, matched))
    4770              :                 {
    4771              :                     /* nah, it's not this item */
    4772          138 :                     item = NULL;
    4773          138 :                     break;
    4774              :                 }
    4775              :             }
    4776              : 
    4777              :             /*
    4778              :              * If the item has all the matched attributes, we know it's the
    4779              :              * right one - there can't be a better one. matching more.
    4780              :              */
    4781          351 :             if (item)
    4782          213 :                 break;
    4783              :         }
    4784              : 
    4785              :         /*
    4786              :          * Make sure we found an item. There has to be one, because ndistinct
    4787              :          * statistics includes all combinations of attributes.
    4788              :          */
    4789          213 :         if (!item)
    4790            0 :             elog(ERROR, "corrupt MVNDistinct entry");
    4791              : 
    4792              :         /* Form the output varinfo list, keeping only unmatched ones */
    4793          744 :         foreach(lc, *varinfos)
    4794              :         {
    4795          531 :             GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc);
    4796              :             ListCell   *lc3;
    4797          531 :             bool        found = false;
    4798              : 
    4799              :             /*
    4800              :              * Let's look at plain variables first, because it's the most
    4801              :              * common case and the check is quite cheap. We can simply get the
    4802              :              * attnum and check (with an offset) matched bitmap.
    4803              :              */
    4804          531 :             if (IsA(varinfo->var, Var))
    4805          435 :             {
    4806          438 :                 AttrNumber  attnum = ((Var *) varinfo->var)->varattno;
    4807              : 
    4808              :                 /*
    4809              :                  * If it's a system attribute, we're done. We don't support
    4810              :                  * extended statistics on system attributes, so it's clearly
    4811              :                  * not matched. Just keep the expression and continue.
    4812              :                  */
    4813          438 :                 if (!AttrNumberIsForUserDefinedAttr(attnum))
    4814              :                 {
    4815            3 :                     newlist = lappend(newlist, varinfo);
    4816            3 :                     continue;
    4817              :                 }
    4818              : 
    4819              :                 /* apply the same offset as above */
    4820          435 :                 attnum += attnum_offset;
    4821              : 
    4822              :                 /* if it's not matched, keep the varinfo */
    4823          435 :                 if (!bms_is_member(attnum, matched))
    4824           60 :                     newlist = lappend(newlist, varinfo);
    4825              : 
    4826              :                 /* The rest of the loop deals with complex expressions. */
    4827          435 :                 continue;
    4828              :             }
    4829              : 
    4830              :             /*
    4831              :              * Process complex expressions, not just simple Vars.
    4832              :              *
    4833              :              * First, we search for an exact match of an expression. If we
    4834              :              * find one, we can just discard the whole GroupVarInfo, with all
    4835              :              * the variables we extracted from it.
    4836              :              *
    4837              :              * Otherwise we inspect the individual vars, and try matching it
    4838              :              * to variables in the item.
    4839              :              */
    4840          153 :             foreach(lc3, matched_info->exprs)
    4841              :             {
    4842          138 :                 Node       *expr = (Node *) lfirst(lc3);
    4843              : 
    4844          138 :                 if (equal(varinfo->var, expr))
    4845              :                 {
    4846           78 :                     found = true;
    4847           78 :                     break;
    4848              :                 }
    4849              :             }
    4850              : 
    4851              :             /* found exact match, skip */
    4852           93 :             if (found)
    4853           78 :                 continue;
    4854              : 
    4855           15 :             newlist = lappend(newlist, varinfo);
    4856              :         }
    4857              : 
    4858          213 :         *varinfos = newlist;
    4859          213 :         *ndistinct = item->ndistinct;
    4860          213 :         return true;
    4861              :     }
    4862              : 
    4863            0 :     return false;
    4864              : }
    4865              : 
    4866              : /*
    4867              :  * convert_to_scalar
    4868              :  *    Convert non-NULL values of the indicated types to the comparison
    4869              :  *    scale needed by scalarineqsel().
    4870              :  *    Returns "true" if successful.
    4871              :  *
    4872              :  * XXX this routine is a hack: ideally we should look up the conversion
    4873              :  * subroutines in pg_type.
    4874              :  *
    4875              :  * All numeric datatypes are simply converted to their equivalent
    4876              :  * "double" values.  (NUMERIC values that are outside the range of "double"
    4877              :  * are clamped to +/- HUGE_VAL.)
    4878              :  *
    4879              :  * String datatypes are converted by convert_string_to_scalar(),
    4880              :  * which is explained below.  The reason why this routine deals with
    4881              :  * three values at a time, not just one, is that we need it for strings.
    4882              :  *
    4883              :  * The bytea datatype is just enough different from strings that it has
    4884              :  * to be treated separately.
    4885              :  *
    4886              :  * The several datatypes representing absolute times are all converted
    4887              :  * to Timestamp, which is actually an int64, and then we promote that to
    4888              :  * a double.  Note this will give correct results even for the "special"
    4889              :  * values of Timestamp, since those are chosen to compare correctly;
    4890              :  * see timestamp_cmp.
    4891              :  *
    4892              :  * The several datatypes representing relative times (intervals) are all
    4893              :  * converted to measurements expressed in seconds.
    4894              :  */
    4895              : static bool
    4896        48970 : convert_to_scalar(Datum value, Oid valuetypid, Oid collid, double *scaledvalue,
    4897              :                   Datum lobound, Datum hibound, Oid boundstypid,
    4898              :                   double *scaledlobound, double *scaledhibound)
    4899              : {
    4900        48970 :     bool        failure = false;
    4901              : 
    4902              :     /*
    4903              :      * Both the valuetypid and the boundstypid should exactly match the
    4904              :      * declared input type(s) of the operator we are invoked for.  However,
    4905              :      * extensions might try to use scalarineqsel as estimator for operators
    4906              :      * with input type(s) we don't handle here; in such cases, we want to
    4907              :      * return false, not fail.  In any case, we mustn't assume that valuetypid
    4908              :      * and boundstypid are identical.
    4909              :      *
    4910              :      * XXX The histogram we are interpolating between points of could belong
    4911              :      * to a column that's only binary-compatible with the declared type. In
    4912              :      * essence we are assuming that the semantics of binary-compatible types
    4913              :      * are enough alike that we can use a histogram generated with one type's
    4914              :      * operators to estimate selectivity for the other's.  This is outright
    4915              :      * wrong in some cases --- in particular signed versus unsigned
    4916              :      * interpretation could trip us up.  But it's useful enough in the
    4917              :      * majority of cases that we do it anyway.  Should think about more
    4918              :      * rigorous ways to do it.
    4919              :      */
    4920        48970 :     switch (valuetypid)
    4921              :     {
    4922              :             /*
    4923              :              * Built-in numeric types
    4924              :              */
    4925        45327 :         case BOOLOID:
    4926              :         case INT2OID:
    4927              :         case INT4OID:
    4928              :         case INT8OID:
    4929              :         case FLOAT4OID:
    4930              :         case FLOAT8OID:
    4931              :         case NUMERICOID:
    4932              :         case OIDOID:
    4933              :         case REGPROCOID:
    4934              :         case REGPROCEDUREOID:
    4935              :         case REGOPEROID:
    4936              :         case REGOPERATOROID:
    4937              :         case REGCLASSOID:
    4938              :         case REGTYPEOID:
    4939              :         case REGCOLLATIONOID:
    4940              :         case REGCONFIGOID:
    4941              :         case REGDICTIONARYOID:
    4942              :         case REGROLEOID:
    4943              :         case REGNAMESPACEOID:
    4944              :         case REGDATABASEOID:
    4945        45327 :             *scaledvalue = convert_numeric_to_scalar(value, valuetypid,
    4946              :                                                      &failure);
    4947        45327 :             *scaledlobound = convert_numeric_to_scalar(lobound, boundstypid,
    4948              :                                                        &failure);
    4949        45327 :             *scaledhibound = convert_numeric_to_scalar(hibound, boundstypid,
    4950              :                                                        &failure);
    4951        45327 :             return !failure;
    4952              : 
    4953              :             /*
    4954              :              * Built-in string types
    4955              :              */
    4956         3643 :         case CHAROID:
    4957              :         case BPCHAROID:
    4958              :         case VARCHAROID:
    4959              :         case TEXTOID:
    4960              :         case NAMEOID:
    4961              :             {
    4962         3643 :                 char       *valstr = convert_string_datum(value, valuetypid,
    4963              :                                                           collid, &failure);
    4964         3643 :                 char       *lostr = convert_string_datum(lobound, boundstypid,
    4965              :                                                          collid, &failure);
    4966         3643 :                 char       *histr = convert_string_datum(hibound, boundstypid,
    4967              :                                                          collid, &failure);
    4968              : 
    4969              :                 /*
    4970              :                  * Bail out if any of the values is not of string type.  We
    4971              :                  * might leak converted strings for the other value(s), but
    4972              :                  * that's not worth troubling over.
    4973              :                  */
    4974         3643 :                 if (failure)
    4975            0 :                     return false;
    4976              : 
    4977         3643 :                 convert_string_to_scalar(valstr, scaledvalue,
    4978              :                                          lostr, scaledlobound,
    4979              :                                          histr, scaledhibound);
    4980         3643 :                 pfree(valstr);
    4981         3643 :                 pfree(lostr);
    4982         3643 :                 pfree(histr);
    4983         3643 :                 return true;
    4984              :             }
    4985              : 
    4986              :             /*
    4987              :              * Built-in bytea type
    4988              :              */
    4989            0 :         case BYTEAOID:
    4990              :             {
    4991              :                 /* We only support bytea vs bytea comparison */
    4992            0 :                 if (boundstypid != BYTEAOID)
    4993            0 :                     return false;
    4994            0 :                 convert_bytea_to_scalar(value, scaledvalue,
    4995              :                                         lobound, scaledlobound,
    4996              :                                         hibound, scaledhibound);
    4997            0 :                 return true;
    4998              :             }
    4999              : 
    5000              :             /*
    5001              :              * Built-in time types
    5002              :              */
    5003            0 :         case TIMESTAMPOID:
    5004              :         case TIMESTAMPTZOID:
    5005              :         case DATEOID:
    5006              :         case INTERVALOID:
    5007              :         case TIMEOID:
    5008              :         case TIMETZOID:
    5009            0 :             *scaledvalue = convert_timevalue_to_scalar(value, valuetypid,
    5010              :                                                        &failure);
    5011            0 :             *scaledlobound = convert_timevalue_to_scalar(lobound, boundstypid,
    5012              :                                                          &failure);
    5013            0 :             *scaledhibound = convert_timevalue_to_scalar(hibound, boundstypid,
    5014              :                                                          &failure);
    5015            0 :             return !failure;
    5016              : 
    5017              :             /*
    5018              :              * Built-in network types
    5019              :              */
    5020            0 :         case INETOID:
    5021              :         case CIDROID:
    5022              :         case MACADDROID:
    5023              :         case MACADDR8OID:
    5024            0 :             *scaledvalue = convert_network_to_scalar(value, valuetypid,
    5025              :                                                      &failure);
    5026            0 :             *scaledlobound = convert_network_to_scalar(lobound, boundstypid,
    5027              :                                                        &failure);
    5028            0 :             *scaledhibound = convert_network_to_scalar(hibound, boundstypid,
    5029              :                                                        &failure);
    5030            0 :             return !failure;
    5031              :     }
    5032              :     /* Don't know how to convert */
    5033            0 :     *scaledvalue = *scaledlobound = *scaledhibound = 0;
    5034            0 :     return false;
    5035              : }
    5036              : 
    5037              : /*
    5038              :  * Do convert_to_scalar()'s work for any numeric data type.
    5039              :  *
    5040              :  * On failure (e.g., unsupported typid), set *failure to true;
    5041              :  * otherwise, that variable is not changed.
    5042              :  */
    5043              : static double
    5044       135981 : convert_numeric_to_scalar(Datum value, Oid typid, bool *failure)
    5045              : {
    5046       135981 :     switch (typid)
    5047              :     {
    5048            0 :         case BOOLOID:
    5049            0 :             return (double) DatumGetBool(value);
    5050            6 :         case INT2OID:
    5051            6 :             return (double) DatumGetInt16(value);
    5052        15957 :         case INT4OID:
    5053        15957 :             return (double) DatumGetInt32(value);
    5054            0 :         case INT8OID:
    5055            0 :             return (double) DatumGetInt64(value);
    5056            0 :         case FLOAT4OID:
    5057            0 :             return (double) DatumGetFloat4(value);
    5058           27 :         case FLOAT8OID:
    5059           27 :             return (double) DatumGetFloat8(value);
    5060            0 :         case NUMERICOID:
    5061              :             /* Note: out-of-range values will be clamped to +-HUGE_VAL */
    5062            0 :             return (double)
    5063            0 :                 DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
    5064              :                                                    value));
    5065       119991 :         case OIDOID:
    5066              :         case REGPROCOID:
    5067              :         case REGPROCEDUREOID:
    5068              :         case REGOPEROID:
    5069              :         case REGOPERATOROID:
    5070              :         case REGCLASSOID:
    5071              :         case REGTYPEOID:
    5072              :         case REGCOLLATIONOID:
    5073              :         case REGCONFIGOID:
    5074              :         case REGDICTIONARYOID:
    5075              :         case REGROLEOID:
    5076              :         case REGNAMESPACEOID:
    5077              :         case REGDATABASEOID:
    5078              :             /* we can treat OIDs as integers... */
    5079       119991 :             return (double) DatumGetObjectId(value);
    5080              :     }
    5081              : 
    5082            0 :     *failure = true;
    5083            0 :     return 0;
    5084              : }
    5085              : 
    5086              : /*
    5087              :  * Do convert_to_scalar()'s work for any character-string data type.
    5088              :  *
    5089              :  * String datatypes are converted to a scale that ranges from 0 to 1,
    5090              :  * where we visualize the bytes of the string as fractional digits.
    5091              :  *
    5092              :  * We do not want the base to be 256, however, since that tends to
    5093              :  * generate inflated selectivity estimates; few databases will have
    5094              :  * occurrences of all 256 possible byte values at each position.
    5095              :  * Instead, use the smallest and largest byte values seen in the bounds
    5096              :  * as the estimated range for each byte, after some fudging to deal with
    5097              :  * the fact that we probably aren't going to see the full range that way.
    5098              :  *
    5099              :  * An additional refinement is that we discard any common prefix of the
    5100              :  * three strings before computing the scaled values.  This allows us to
    5101              :  * "zoom in" when we encounter a narrow data range.  An example is a phone
    5102              :  * number database where all the values begin with the same area code.
    5103              :  * (Actually, the bounds will be adjacent histogram-bin-boundary values,
    5104              :  * so this is more likely to happen than you might think.)
    5105              :  */
    5106              : static void
    5107         3643 : convert_string_to_scalar(char *value,
    5108              :                          double *scaledvalue,
    5109              :                          char *lobound,
    5110              :                          double *scaledlobound,
    5111              :                          char *hibound,
    5112              :                          double *scaledhibound)
    5113              : {
    5114              :     int         rangelo,
    5115              :                 rangehi;
    5116              :     char       *sptr;
    5117              : 
    5118         3643 :     rangelo = rangehi = (unsigned char) hibound[0];
    5119        45244 :     for (sptr = lobound; *sptr; sptr++)
    5120              :     {
    5121        41601 :         if (rangelo > (unsigned char) *sptr)
    5122         8626 :             rangelo = (unsigned char) *sptr;
    5123        41601 :         if (rangehi < (unsigned char) *sptr)
    5124         4486 :             rangehi = (unsigned char) *sptr;
    5125              :     }
    5126        44036 :     for (sptr = hibound; *sptr; sptr++)
    5127              :     {
    5128        40393 :         if (rangelo > (unsigned char) *sptr)
    5129          617 :             rangelo = (unsigned char) *sptr;
    5130        40393 :         if (rangehi < (unsigned char) *sptr)
    5131         1680 :             rangehi = (unsigned char) *sptr;
    5132              :     }
    5133              :     /* If range includes any upper-case ASCII chars, make it include all */
    5134         3643 :     if (rangelo <= 'Z' && rangehi >= 'A')
    5135              :     {
    5136          649 :         if (rangelo > 'A')
    5137          111 :             rangelo = 'A';
    5138          649 :         if (rangehi < 'Z')
    5139          240 :             rangehi = 'Z';
    5140              :     }
    5141              :     /* Ditto lower-case */
    5142         3643 :     if (rangelo <= 'z' && rangehi >= 'a')
    5143              :     {
    5144         3392 :         if (rangelo > 'a')
    5145            5 :             rangelo = 'a';
    5146         3392 :         if (rangehi < 'z')
    5147         3358 :             rangehi = 'z';
    5148              :     }
    5149              :     /* Ditto digits */
    5150         3643 :     if (rangelo <= '9' && rangehi >= '0')
    5151              :     {
    5152          309 :         if (rangelo > '0')
    5153          262 :             rangelo = '0';
    5154          309 :         if (rangehi < '9')
    5155            7 :             rangehi = '9';
    5156              :     }
    5157              : 
    5158              :     /*
    5159              :      * If range includes less than 10 chars, assume we have not got enough
    5160              :      * data, and make it include regular ASCII set.
    5161              :      */
    5162         3643 :     if (rangehi - rangelo < 9)
    5163              :     {
    5164            0 :         rangelo = ' ';
    5165            0 :         rangehi = 127;
    5166              :     }
    5167              : 
    5168              :     /*
    5169              :      * Now strip any common prefix of the three strings.
    5170              :      */
    5171         7556 :     while (*lobound)
    5172              :     {
    5173         7556 :         if (*lobound != *hibound || *lobound != *value)
    5174              :             break;
    5175         3913 :         lobound++, hibound++, value++;
    5176              :     }
    5177              : 
    5178              :     /*
    5179              :      * Now we can do the conversions.
    5180              :      */
    5181         3643 :     *scaledvalue = convert_one_string_to_scalar(value, rangelo, rangehi);
    5182         3643 :     *scaledlobound = convert_one_string_to_scalar(lobound, rangelo, rangehi);
    5183         3643 :     *scaledhibound = convert_one_string_to_scalar(hibound, rangelo, rangehi);
    5184         3643 : }
    5185              : 
    5186              : static double
    5187        10929 : convert_one_string_to_scalar(char *value, int rangelo, int rangehi)
    5188              : {
    5189        10929 :     int         slen = strlen(value);
    5190              :     double      num,
    5191              :                 denom,
    5192              :                 base;
    5193              : 
    5194        10929 :     if (slen <= 0)
    5195            0 :         return 0.0;             /* empty string has scalar value 0 */
    5196              : 
    5197              :     /*
    5198              :      * There seems little point in considering more than a dozen bytes from
    5199              :      * the string.  Since base is at least 10, that will give us nominal
    5200              :      * resolution of at least 12 decimal digits, which is surely far more
    5201              :      * precision than this estimation technique has got anyway (especially in
    5202              :      * non-C locales).  Also, even with the maximum possible base of 256, this
    5203              :      * ensures denom cannot grow larger than 256^13 = 2.03e31, which will not
    5204              :      * overflow on any known machine.
    5205              :      */
    5206        10929 :     if (slen > 12)
    5207         2815 :         slen = 12;
    5208              : 
    5209              :     /* Convert initial characters to fraction */
    5210        10929 :     base = rangehi - rangelo + 1;
    5211        10929 :     num = 0.0;
    5212        10929 :     denom = base;
    5213        91320 :     while (slen-- > 0)
    5214              :     {
    5215        80391 :         int         ch = (unsigned char) *value++;
    5216              : 
    5217        80391 :         if (ch < rangelo)
    5218          104 :             ch = rangelo - 1;
    5219        80287 :         else if (ch > rangehi)
    5220            0 :             ch = rangehi + 1;
    5221        80391 :         num += ((double) (ch - rangelo)) / denom;
    5222        80391 :         denom *= base;
    5223              :     }
    5224              : 
    5225        10929 :     return num;
    5226              : }
    5227              : 
    5228              : /*
    5229              :  * Convert a string-type Datum into a palloc'd, null-terminated string.
    5230              :  *
    5231              :  * On failure (e.g., unsupported typid), set *failure to true;
    5232              :  * otherwise, that variable is not changed.  (We'll return NULL on failure.)
    5233              :  *
    5234              :  * When using a non-C locale, we must pass the string through pg_strxfrm()
    5235              :  * before continuing, so as to generate correct locale-specific results.
    5236              :  */
    5237              : static char *
    5238        10929 : convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure)
    5239              : {
    5240              :     char       *val;
    5241              :     pg_locale_t mylocale;
    5242              : 
    5243        10929 :     switch (typid)
    5244              :     {
    5245            0 :         case CHAROID:
    5246            0 :             val = (char *) palloc(2);
    5247            0 :             val[0] = DatumGetChar(value);
    5248            0 :             val[1] = '\0';
    5249            0 :             break;
    5250         3375 :         case BPCHAROID:
    5251              :         case VARCHAROID:
    5252              :         case TEXTOID:
    5253         3375 :             val = TextDatumGetCString(value);
    5254         3375 :             break;
    5255         7554 :         case NAMEOID:
    5256              :             {
    5257         7554 :                 NameData   *nm = (NameData *) DatumGetPointer(value);
    5258              : 
    5259         7554 :                 val = pstrdup(NameStr(*nm));
    5260         7554 :                 break;
    5261              :             }
    5262            0 :         default:
    5263            0 :             *failure = true;
    5264            0 :             return NULL;
    5265              :     }
    5266              : 
    5267        10929 :     mylocale = pg_newlocale_from_collation(collid);
    5268              : 
    5269        10929 :     if (!mylocale->collate_is_c)
    5270              :     {
    5271              :         char       *xfrmstr;
    5272              :         size_t      xfrmlen;
    5273              :         size_t      xfrmlen2 PG_USED_FOR_ASSERTS_ONLY;
    5274              : 
    5275              :         /*
    5276              :          * XXX: We could guess at a suitable output buffer size and only call
    5277              :          * pg_strxfrm() twice if our guess is too small.
    5278              :          *
    5279              :          * XXX: strxfrm doesn't support UTF-8 encoding on Win32, it can return
    5280              :          * bogus data or set an error. This is not really a problem unless it
    5281              :          * crashes since it will only give an estimation error and nothing
    5282              :          * fatal.
    5283              :          *
    5284              :          * XXX: we do not check pg_strxfrm_enabled(). On some platforms and in
    5285              :          * some cases, libc strxfrm() may return the wrong results, but that
    5286              :          * will only lead to an estimation error.
    5287              :          */
    5288           36 :         xfrmlen = pg_strxfrm(NULL, val, 0, mylocale);
    5289              : #ifdef WIN32
    5290              : 
    5291              :         /*
    5292              :          * On Windows, strxfrm returns INT_MAX when an error occurs. Instead
    5293              :          * of trying to allocate this much memory (and fail), just return the
    5294              :          * original string unmodified as if we were in the C locale.
    5295              :          */
    5296              :         if (xfrmlen == INT_MAX)
    5297              :             return val;
    5298              : #endif
    5299           36 :         xfrmstr = (char *) palloc(xfrmlen + 1);
    5300           36 :         xfrmlen2 = pg_strxfrm(xfrmstr, val, xfrmlen + 1, mylocale);
    5301              : 
    5302              :         /*
    5303              :          * Some systems (e.g., glibc) can return a smaller value from the
    5304              :          * second call than the first; thus the Assert must be <= not ==.
    5305              :          */
    5306              :         Assert(xfrmlen2 <= xfrmlen);
    5307           36 :         pfree(val);
    5308           36 :         val = xfrmstr;
    5309              :     }
    5310              : 
    5311        10929 :     return val;
    5312              : }
    5313              : 
    5314              : /*
    5315              :  * Do convert_to_scalar()'s work for any bytea data type.
    5316              :  *
    5317              :  * Very similar to convert_string_to_scalar except we can't assume
    5318              :  * null-termination and therefore pass explicit lengths around.
    5319              :  *
    5320              :  * Also, assumptions about likely "normal" ranges of characters have been
    5321              :  * removed - a data range of 0..255 is always used, for now.  (Perhaps
    5322              :  * someday we will add information about actual byte data range to
    5323              :  * pg_statistic.)
    5324              :  */
    5325              : static void
    5326            0 : convert_bytea_to_scalar(Datum value,
    5327              :                         double *scaledvalue,
    5328              :                         Datum lobound,
    5329              :                         double *scaledlobound,
    5330              :                         Datum hibound,
    5331              :                         double *scaledhibound)
    5332              : {
    5333            0 :     bytea      *valuep = DatumGetByteaPP(value);
    5334            0 :     bytea      *loboundp = DatumGetByteaPP(lobound);
    5335            0 :     bytea      *hiboundp = DatumGetByteaPP(hibound);
    5336              :     int         rangelo,
    5337              :                 rangehi,
    5338            0 :                 valuelen = VARSIZE_ANY_EXHDR(valuep),
    5339            0 :                 loboundlen = VARSIZE_ANY_EXHDR(loboundp),
    5340            0 :                 hiboundlen = VARSIZE_ANY_EXHDR(hiboundp),
    5341              :                 i,
    5342              :                 minlen;
    5343            0 :     unsigned char *valstr = (unsigned char *) VARDATA_ANY(valuep);
    5344            0 :     unsigned char *lostr = (unsigned char *) VARDATA_ANY(loboundp);
    5345            0 :     unsigned char *histr = (unsigned char *) VARDATA_ANY(hiboundp);
    5346              : 
    5347              :     /*
    5348              :      * Assume bytea data is uniformly distributed across all byte values.
    5349              :      */
    5350            0 :     rangelo = 0;
    5351            0 :     rangehi = 255;
    5352              : 
    5353              :     /*
    5354              :      * Now strip any common prefix of the three strings.
    5355              :      */
    5356            0 :     minlen = Min(Min(valuelen, loboundlen), hiboundlen);
    5357            0 :     for (i = 0; i < minlen; i++)
    5358              :     {
    5359            0 :         if (*lostr != *histr || *lostr != *valstr)
    5360              :             break;
    5361            0 :         lostr++, histr++, valstr++;
    5362            0 :         loboundlen--, hiboundlen--, valuelen--;
    5363              :     }
    5364              : 
    5365              :     /*
    5366              :      * Now we can do the conversions.
    5367              :      */
    5368            0 :     *scaledvalue = convert_one_bytea_to_scalar(valstr, valuelen, rangelo, rangehi);
    5369            0 :     *scaledlobound = convert_one_bytea_to_scalar(lostr, loboundlen, rangelo, rangehi);
    5370            0 :     *scaledhibound = convert_one_bytea_to_scalar(histr, hiboundlen, rangelo, rangehi);
    5371            0 : }
    5372              : 
    5373              : static double
    5374            0 : convert_one_bytea_to_scalar(unsigned char *value, int valuelen,
    5375              :                             int rangelo, int rangehi)
    5376              : {
    5377              :     double      num,
    5378              :                 denom,
    5379              :                 base;
    5380              : 
    5381            0 :     if (valuelen <= 0)
    5382            0 :         return 0.0;             /* empty string has scalar value 0 */
    5383              : 
    5384              :     /*
    5385              :      * Since base is 256, need not consider more than about 10 chars (even
    5386              :      * this many seems like overkill)
    5387              :      */
    5388            0 :     if (valuelen > 10)
    5389            0 :         valuelen = 10;
    5390              : 
    5391              :     /* Convert initial characters to fraction */
    5392            0 :     base = rangehi - rangelo + 1;
    5393            0 :     num = 0.0;
    5394            0 :     denom = base;
    5395            0 :     while (valuelen-- > 0)
    5396              :     {
    5397            0 :         int         ch = *value++;
    5398              : 
    5399            0 :         if (ch < rangelo)
    5400            0 :             ch = rangelo - 1;
    5401            0 :         else if (ch > rangehi)
    5402            0 :             ch = rangehi + 1;
    5403            0 :         num += ((double) (ch - rangelo)) / denom;
    5404            0 :         denom *= base;
    5405              :     }
    5406              : 
    5407            0 :     return num;
    5408              : }
    5409              : 
    5410              : /*
    5411              :  * Do convert_to_scalar()'s work for any timevalue data type.
    5412              :  *
    5413              :  * On failure (e.g., unsupported typid), set *failure to true;
    5414              :  * otherwise, that variable is not changed.
    5415              :  */
    5416              : static double
    5417            0 : convert_timevalue_to_scalar(Datum value, Oid typid, bool *failure)
    5418              : {
    5419            0 :     switch (typid)
    5420              :     {
    5421            0 :         case TIMESTAMPOID:
    5422            0 :             return DatumGetTimestamp(value);
    5423            0 :         case TIMESTAMPTZOID:
    5424            0 :             return DatumGetTimestampTz(value);
    5425            0 :         case DATEOID:
    5426            0 :             return date2timestamp_no_overflow(DatumGetDateADT(value));
    5427            0 :         case INTERVALOID:
    5428              :             {
    5429            0 :                 Interval   *interval = DatumGetIntervalP(value);
    5430              : 
    5431              :                 /*
    5432              :                  * Convert the month part of Interval to days using assumed
    5433              :                  * average month length of 365.25/12.0 days.  Not too
    5434              :                  * accurate, but plenty good enough for our purposes.
    5435              :                  *
    5436              :                  * This also works for infinite intervals, which just have all
    5437              :                  * fields set to INT_MIN/INT_MAX, and so will produce a result
    5438              :                  * smaller/larger than any finite interval.
    5439              :                  */
    5440            0 :                 return interval->time + interval->day * (double) USECS_PER_DAY +
    5441            0 :                     interval->month * ((DAYS_PER_YEAR / (double) MONTHS_PER_YEAR) * USECS_PER_DAY);
    5442              :             }
    5443            0 :         case TIMEOID:
    5444            0 :             return DatumGetTimeADT(value);
    5445            0 :         case TIMETZOID:
    5446              :             {
    5447            0 :                 TimeTzADT  *timetz = DatumGetTimeTzADTP(value);
    5448              : 
    5449              :                 /* use GMT-equivalent time */
    5450            0 :                 return (double) (timetz->time + (timetz->zone * 1000000.0));
    5451              :             }
    5452              :     }
    5453              : 
    5454            0 :     *failure = true;
    5455            0 :     return 0;
    5456              : }
    5457              : 
    5458              : 
    5459              : /*
    5460              :  * get_restriction_variable
    5461              :  *      Examine the args of a restriction clause to see if it's of the
    5462              :  *      form (variable op pseudoconstant) or (pseudoconstant op variable),
    5463              :  *      where "variable" could be either a Var or an expression in vars of a
    5464              :  *      single relation.  If so, extract information about the variable,
    5465              :  *      and also indicate which side it was on and the other argument.
    5466              :  *
    5467              :  * Inputs:
    5468              :  *  root: the planner info
    5469              :  *  args: clause argument list
    5470              :  *  varRelid: see specs for restriction selectivity functions
    5471              :  *
    5472              :  * Outputs: (these are valid only if true is returned)
    5473              :  *  *vardata: gets information about variable (see examine_variable)
    5474              :  *  *other: gets other clause argument, aggressively reduced to a constant
    5475              :  *  *varonleft: set true if variable is on the left, false if on the right
    5476              :  *
    5477              :  * Returns true if a variable is identified, otherwise false.
    5478              :  *
    5479              :  * Note: if there are Vars on both sides of the clause, we must fail, because
    5480              :  * callers are expecting that the other side will act like a pseudoconstant.
    5481              :  */
    5482              : bool
    5483       472790 : get_restriction_variable(PlannerInfo *root, List *args, int varRelid,
    5484              :                          VariableStatData *vardata, Node **other,
    5485              :                          bool *varonleft)
    5486              : {
    5487              :     Node       *left,
    5488              :                *right;
    5489              :     VariableStatData rdata;
    5490              : 
    5491              :     /* Fail if not a binary opclause (probably shouldn't happen) */
    5492       472790 :     if (list_length(args) != 2)
    5493            0 :         return false;
    5494              : 
    5495       472790 :     left = (Node *) linitial(args);
    5496       472790 :     right = (Node *) lsecond(args);
    5497              : 
    5498              :     /*
    5499              :      * Examine both sides.  Note that when varRelid is nonzero, Vars of other
    5500              :      * relations will be treated as pseudoconstants.
    5501              :      */
    5502       472790 :     examine_variable(root, left, varRelid, vardata);
    5503       472790 :     examine_variable(root, right, varRelid, &rdata);
    5504              : 
    5505              :     /*
    5506              :      * If one side is a variable and the other not, we win.
    5507              :      */
    5508       472790 :     if (vardata->rel && rdata.rel == NULL)
    5509              :     {
    5510       421001 :         *varonleft = true;
    5511       421001 :         *other = estimate_expression_value(root, rdata.var);
    5512              :         /* Assume we need no ReleaseVariableStats(rdata) here */
    5513       420998 :         return true;
    5514              :     }
    5515              : 
    5516        51789 :     if (vardata->rel == NULL && rdata.rel)
    5517              :     {
    5518        48403 :         *varonleft = false;
    5519        48403 :         *other = estimate_expression_value(root, vardata->var);
    5520              :         /* Assume we need no ReleaseVariableStats(*vardata) here */
    5521        48403 :         *vardata = rdata;
    5522        48403 :         return true;
    5523              :     }
    5524              : 
    5525              :     /* Oops, clause has wrong structure (probably var op var) */
    5526         3386 :     ReleaseVariableStats(*vardata);
    5527         3386 :     ReleaseVariableStats(rdata);
    5528              : 
    5529         3386 :     return false;
    5530              : }
    5531              : 
    5532              : /*
    5533              :  * get_join_variables
    5534              :  *      Apply examine_variable() to each side of a join clause.
    5535              :  *      Also, attempt to identify whether the join clause has the same
    5536              :  *      or reversed sense compared to the SpecialJoinInfo.
    5537              :  *
    5538              :  * We consider the join clause "normal" if it is "lhs_var OP rhs_var",
    5539              :  * or "reversed" if it is "rhs_var OP lhs_var".  In complicated cases
    5540              :  * where we can't tell for sure, we default to assuming it's normal.
    5541              :  */
    5542              : void
    5543       155153 : get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo,
    5544              :                    VariableStatData *vardata1, VariableStatData *vardata2,
    5545              :                    bool *join_is_reversed)
    5546              : {
    5547              :     Node       *left,
    5548              :                *right;
    5549              : 
    5550       155153 :     if (list_length(args) != 2)
    5551            0 :         elog(ERROR, "join operator should take two arguments");
    5552              : 
    5553       155153 :     left = (Node *) linitial(args);
    5554       155153 :     right = (Node *) lsecond(args);
    5555              : 
    5556       155153 :     examine_variable(root, left, 0, vardata1);
    5557       155153 :     examine_variable(root, right, 0, vardata2);
    5558              : 
    5559       310179 :     if (vardata1->rel &&
    5560       155026 :         bms_is_subset(vardata1->rel->relids, sjinfo->syn_righthand))
    5561        51751 :         *join_is_reversed = true;   /* var1 is on RHS */
    5562       206679 :     else if (vardata2->rel &&
    5563       103277 :              bms_is_subset(vardata2->rel->relids, sjinfo->syn_lefthand))
    5564          169 :         *join_is_reversed = true;   /* var2 is on LHS */
    5565              :     else
    5566       103233 :         *join_is_reversed = false;
    5567       155153 : }
    5568              : 
    5569              : /* statext_expressions_load copies the tuple, so just pfree it. */
    5570              : static void
    5571          831 : ReleaseDummy(HeapTuple tuple)
    5572              : {
    5573          831 :     pfree(tuple);
    5574          831 : }
    5575              : 
    5576              : /*
    5577              :  * examine_variable
    5578              :  *      Try to look up statistical data about an expression.
    5579              :  *      Fill in a VariableStatData struct to describe the expression.
    5580              :  *
    5581              :  * Inputs:
    5582              :  *  root: the planner info
    5583              :  *  node: the expression tree to examine
    5584              :  *  varRelid: see specs for restriction selectivity functions
    5585              :  *
    5586              :  * Outputs: *vardata is filled as follows:
    5587              :  *  var: the input expression (with any phvs or binary relabeling stripped,
    5588              :  *      if it is or contains a variable; but otherwise unchanged)
    5589              :  *  rel: RelOptInfo for relation containing variable; NULL if expression
    5590              :  *      contains no Vars (NOTE this could point to a RelOptInfo of a
    5591              :  *      subquery, not one in the current query).
    5592              :  *  statsTuple: the pg_statistic entry for the variable, if one exists;
    5593              :  *      otherwise NULL.
    5594              :  *  freefunc: pointer to a function to release statsTuple with.
    5595              :  *  vartype: exposed type of the expression; this should always match
    5596              :  *      the declared input type of the operator we are estimating for.
    5597              :  *  atttype, atttypmod: actual type/typmod of the "var" expression.  This is
    5598              :  *      commonly the same as the exposed type of the variable argument,
    5599              :  *      but can be different in binary-compatible-type cases.
    5600              :  *  isunique: true if we were able to match the var to a unique index, a
    5601              :  *      single-column DISTINCT or GROUP-BY clause, implying its values are
    5602              :  *      unique for this query.  (Caution: this should be trusted for
    5603              :  *      statistical purposes only, since we do not check indimmediate nor
    5604              :  *      verify that the exact same definition of equality applies.)
    5605              :  *  acl_ok: true if current user has permission to read all table rows from
    5606              :  *      the column(s) underlying the pg_statistic entry.  This is consulted by
    5607              :  *      statistic_proc_security_check().
    5608              :  *
    5609              :  * Caller is responsible for doing ReleaseVariableStats() before exiting.
    5610              :  */
    5611              : void
    5612      1895011 : examine_variable(PlannerInfo *root, Node *node, int varRelid,
    5613              :                  VariableStatData *vardata)
    5614              : {
    5615              :     Node       *basenode;
    5616              :     Relids      varnos;
    5617              :     Relids      basevarnos;
    5618              :     RelOptInfo *onerel;
    5619              : 
    5620              :     /* Make sure we don't return dangling pointers in vardata */
    5621     13265077 :     MemSet(vardata, 0, sizeof(VariableStatData));
    5622              : 
    5623              :     /* Save the exposed type of the expression */
    5624      1895011 :     vardata->vartype = exprType(node);
    5625              : 
    5626              :     /*
    5627              :      * PlaceHolderVars are transparent for the purpose of statistics lookup;
    5628              :      * they do not alter the value distribution of the underlying expression.
    5629              :      * However, they can obscure the structure, preventing us from recognizing
    5630              :      * matches to base columns, index expressions, or extended statistics.  So
    5631              :      * strip them out first.
    5632              :      */
    5633      1895011 :     basenode = strip_all_phvs_deep(root, node);
    5634              : 
    5635              :     /*
    5636              :      * Look inside any binary-compatible relabeling.  We need to handle nested
    5637              :      * RelabelType nodes here, because the prior stripping of PlaceHolderVars
    5638              :      * may have brought separate RelabelTypes into adjacency.
    5639              :      */
    5640      1919779 :     while (IsA(basenode, RelabelType))
    5641        24768 :         basenode = (Node *) ((RelabelType *) basenode)->arg;
    5642              : 
    5643              :     /* Fast path for a simple Var */
    5644      1895011 :     if (IsA(basenode, Var) &&
    5645       485905 :         (varRelid == 0 || varRelid == ((Var *) basenode)->varno))
    5646              :     {
    5647      1360299 :         Var        *var = (Var *) basenode;
    5648              : 
    5649              :         /* Set up result fields other than the stats tuple */
    5650      1360299 :         vardata->var = basenode; /* return Var without phvs or relabeling */
    5651      1360299 :         vardata->rel = find_base_rel(root, var->varno);
    5652      1360299 :         vardata->atttype = var->vartype;
    5653      1360299 :         vardata->atttypmod = var->vartypmod;
    5654      1360299 :         vardata->isunique = has_unique_index(vardata->rel, var->varattno);
    5655              : 
    5656              :         /* Try to locate some stats */
    5657      1360299 :         examine_simple_variable(root, var, vardata);
    5658              : 
    5659      1360299 :         return;
    5660              :     }
    5661              : 
    5662              :     /*
    5663              :      * Okay, it's a more complicated expression.  Determine variable
    5664              :      * membership.  Note that when varRelid isn't zero, only vars of that
    5665              :      * relation are considered "real" vars.
    5666              :      */
    5667       534712 :     varnos = pull_varnos(root, basenode);
    5668       534712 :     basevarnos = bms_difference(varnos, root->outer_join_rels);
    5669              : 
    5670       534712 :     onerel = NULL;
    5671              : 
    5672       534712 :     if (bms_is_empty(basevarnos))
    5673              :     {
    5674              :         /* No Vars at all ... must be pseudo-constant clause */
    5675              :     }
    5676              :     else
    5677              :     {
    5678              :         int         relid;
    5679              : 
    5680              :         /* Check if the expression is in vars of a single base relation */
    5681       281792 :         if (bms_get_singleton_member(basevarnos, &relid))
    5682              :         {
    5683       279371 :             if (varRelid == 0 || varRelid == relid)
    5684              :             {
    5685        36787 :                 onerel = find_base_rel(root, relid);
    5686        36787 :                 vardata->rel = onerel;
    5687        36787 :                 node = basenode;    /* strip any phvs or relabeling */
    5688              :             }
    5689              :             /* else treat it as a constant */
    5690              :         }
    5691              :         else
    5692              :         {
    5693              :             /* varnos has multiple relids */
    5694         2421 :             if (varRelid == 0)
    5695              :             {
    5696              :                 /* treat it as a variable of a join relation */
    5697         1765 :                 vardata->rel = find_join_rel(root, varnos);
    5698         1765 :                 node = basenode;    /* strip any phvs or relabeling */
    5699              :             }
    5700          656 :             else if (bms_is_member(varRelid, varnos))
    5701              :             {
    5702              :                 /* ignore the vars belonging to other relations */
    5703          599 :                 vardata->rel = find_base_rel(root, varRelid);
    5704          599 :                 node = basenode;    /* strip any phvs or relabeling */
    5705              :                 /* note: no point in expressional-index search here */
    5706              :             }
    5707              :             /* else treat it as a constant */
    5708              :         }
    5709              :     }
    5710              : 
    5711       534712 :     bms_free(basevarnos);
    5712              : 
    5713       534712 :     vardata->var = node;
    5714       534712 :     vardata->atttype = exprType(node);
    5715       534712 :     vardata->atttypmod = exprTypmod(node);
    5716              : 
    5717       534712 :     if (onerel)
    5718              :     {
    5719              :         /*
    5720              :          * We have an expression in vars of a single relation.  Try to match
    5721              :          * it to expressional index columns, in hopes of finding some
    5722              :          * statistics.
    5723              :          *
    5724              :          * Note that we consider all index columns including INCLUDE columns,
    5725              :          * since there could be stats for such columns.  But the test for
    5726              :          * uniqueness needs to be warier.
    5727              :          *
    5728              :          * XXX it's conceivable that there are multiple matches with different
    5729              :          * index opfamilies; if so, we need to pick one that matches the
    5730              :          * operator we are estimating for.  FIXME later.
    5731              :          */
    5732              :         ListCell   *ilist;
    5733              :         ListCell   *slist;
    5734              : 
    5735              :         /*
    5736              :          * The nullingrels bits within the expression could prevent us from
    5737              :          * matching it to expressional index columns or to the expressions in
    5738              :          * extended statistics.  So strip them out first.
    5739              :          */
    5740        36787 :         if (bms_overlap(varnos, root->outer_join_rels))
    5741         1289 :             node = remove_nulling_relids(node, root->outer_join_rels, NULL);
    5742              : 
    5743        81912 :         foreach(ilist, onerel->indexlist)
    5744              :         {
    5745        46616 :             IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
    5746              :             ListCell   *indexpr_item;
    5747              :             int         pos;
    5748              : 
    5749        46616 :             indexpr_item = list_head(index->indexprs);
    5750        46616 :             if (indexpr_item == NULL)
    5751        44180 :                 continue;       /* no expressions here... */
    5752              : 
    5753         3417 :             for (pos = 0; pos < index->ncolumns; pos++)
    5754              :             {
    5755         2472 :                 if (index->indexkeys[pos] == 0)
    5756              :                 {
    5757              :                     Node       *indexkey;
    5758              : 
    5759         2436 :                     if (indexpr_item == NULL)
    5760            0 :                         elog(ERROR, "too few entries in indexprs list");
    5761         2436 :                     indexkey = (Node *) lfirst(indexpr_item);
    5762         2436 :                     if (indexkey && IsA(indexkey, RelabelType))
    5763            0 :                         indexkey = (Node *) ((RelabelType *) indexkey)->arg;
    5764         2436 :                     if (equal(node, indexkey))
    5765              :                     {
    5766              :                         /*
    5767              :                          * Found a match ... is it a unique index? Tests here
    5768              :                          * should match has_unique_index().
    5769              :                          */
    5770         1809 :                         if (index->unique &&
    5771          219 :                             index->nkeycolumns == 1 &&
    5772          219 :                             pos == 0 &&
    5773          219 :                             (index->indpred == NIL || index->predOK))
    5774          219 :                             vardata->isunique = true;
    5775              : 
    5776              :                         /*
    5777              :                          * Has it got stats?  We only consider stats for
    5778              :                          * non-partial indexes, since partial indexes probably
    5779              :                          * don't reflect whole-relation statistics; the above
    5780              :                          * check for uniqueness is the only info we take from
    5781              :                          * a partial index.
    5782              :                          *
    5783              :                          * An index stats hook, however, must make its own
    5784              :                          * decisions about what to do with partial indexes.
    5785              :                          */
    5786         1809 :                         if (get_index_stats_hook &&
    5787            0 :                             (*get_index_stats_hook) (root, index->indexoid,
    5788            0 :                                                      pos + 1, vardata))
    5789              :                         {
    5790              :                             /*
    5791              :                              * The hook took control of acquiring a stats
    5792              :                              * tuple.  If it did supply a tuple, it'd better
    5793              :                              * have supplied a freefunc.
    5794              :                              */
    5795            0 :                             if (HeapTupleIsValid(vardata->statsTuple) &&
    5796            0 :                                 !vardata->freefunc)
    5797            0 :                                 elog(ERROR, "no function provided to release variable stats with");
    5798              :                         }
    5799         1809 :                         else if (index->indpred == NIL)
    5800              :                         {
    5801         1809 :                             vardata->statsTuple =
    5802         3618 :                                 SearchSysCache3(STATRELATTINH,
    5803              :                                                 ObjectIdGetDatum(index->indexoid),
    5804         1809 :                                                 Int16GetDatum(pos + 1),
    5805              :                                                 BoolGetDatum(false));
    5806         1809 :                             vardata->freefunc = ReleaseSysCache;
    5807              : 
    5808         1809 :                             if (HeapTupleIsValid(vardata->statsTuple))
    5809              :                             {
    5810              :                                 /*
    5811              :                                  * Test if user has permission to access all
    5812              :                                  * rows from the index's table.
    5813              :                                  *
    5814              :                                  * For simplicity, we insist on the whole
    5815              :                                  * table being selectable, rather than trying
    5816              :                                  * to identify which column(s) the index
    5817              :                                  * depends on.
    5818              :                                  *
    5819              :                                  * Note that for an inheritance child,
    5820              :                                  * permissions are checked on the inheritance
    5821              :                                  * root parent, and whole-table select
    5822              :                                  * privilege on the parent doesn't quite
    5823              :                                  * guarantee that the user could read all
    5824              :                                  * columns of the child.  But in practice it's
    5825              :                                  * unlikely that any interesting security
    5826              :                                  * violation could result from allowing access
    5827              :                                  * to the expression index's stats, so we
    5828              :                                  * allow it anyway.  See similar code in
    5829              :                                  * examine_simple_variable() for additional
    5830              :                                  * comments.
    5831              :                                  */
    5832         1491 :                                 vardata->acl_ok =
    5833         1491 :                                     all_rows_selectable(root,
    5834         1491 :                                                         index->rel->relid,
    5835              :                                                         NULL);
    5836              :                             }
    5837              :                             else
    5838              :                             {
    5839              :                                 /* suppress leakproofness checks later */
    5840          318 :                                 vardata->acl_ok = true;
    5841              :                             }
    5842              :                         }
    5843         1809 :                         if (vardata->statsTuple)
    5844         1491 :                             break;
    5845              :                     }
    5846          945 :                     indexpr_item = lnext(index->indexprs, indexpr_item);
    5847              :                 }
    5848              :             }
    5849         2436 :             if (vardata->statsTuple)
    5850         1491 :                 break;
    5851              :         }
    5852              : 
    5853              :         /*
    5854              :          * Search extended statistics for one with a matching expression.
    5855              :          * There might be multiple ones, so just grab the first one. In the
    5856              :          * future, we might consider the statistics target (and pick the most
    5857              :          * accurate statistics) and maybe some other parameters.
    5858              :          */
    5859        38873 :         foreach(slist, onerel->statlist)
    5860              :         {
    5861         2230 :             StatisticExtInfo *info = (StatisticExtInfo *) lfirst(slist);
    5862         2230 :             RangeTblEntry *rte = planner_rt_fetch(onerel->relid, root);
    5863              :             ListCell   *expr_item;
    5864              :             int         pos;
    5865              : 
    5866              :             /*
    5867              :              * Stop once we've found statistics for the expression (either
    5868              :              * from extended stats, or for an index in the preceding loop).
    5869              :              */
    5870         2230 :             if (vardata->statsTuple)
    5871          144 :                 break;
    5872              : 
    5873              :             /* skip stats without per-expression stats */
    5874         2086 :             if (info->kind != STATS_EXT_EXPRESSIONS)
    5875         1074 :                 continue;
    5876              : 
    5877              :             /* skip stats with mismatching stxdinherit value */
    5878         1012 :             if (info->inherit != rte->inh)
    5879            3 :                 continue;
    5880              : 
    5881         1009 :             pos = 0;
    5882         1660 :             foreach(expr_item, info->exprs)
    5883              :             {
    5884         1483 :                 Node       *expr = (Node *) lfirst(expr_item);
    5885              : 
    5886              :                 Assert(expr);
    5887              : 
    5888              :                 /* strip RelabelType before comparing it */
    5889         1483 :                 if (expr && IsA(expr, RelabelType))
    5890            0 :                     expr = (Node *) ((RelabelType *) expr)->arg;
    5891              : 
    5892              :                 /* found a match, see if we can extract pg_statistic row */
    5893         1483 :                 if (equal(node, expr))
    5894              :                 {
    5895              :                     /*
    5896              :                      * XXX Not sure if we should cache the tuple somewhere.
    5897              :                      * Now we just create a new copy every time.
    5898              :                      */
    5899          832 :                     vardata->statsTuple =
    5900          832 :                         statext_expressions_load(info->statOid, rte->inh, pos);
    5901              : 
    5902              :                     /* Nothing to release if no data found */
    5903          832 :                     if (vardata->statsTuple != NULL)
    5904              :                     {
    5905          831 :                         vardata->freefunc = ReleaseDummy;
    5906              :                     }
    5907              : 
    5908              :                     /*
    5909              :                      * Test if user has permission to access all rows from the
    5910              :                      * table.
    5911              :                      *
    5912              :                      * For simplicity, we insist on the whole table being
    5913              :                      * selectable, rather than trying to identify which
    5914              :                      * column(s) the statistics object depends on.
    5915              :                      *
    5916              :                      * Note that for an inheritance child, permissions are
    5917              :                      * checked on the inheritance root parent, and whole-table
    5918              :                      * select privilege on the parent doesn't quite guarantee
    5919              :                      * that the user could read all columns of the child.  But
    5920              :                      * in practice it's unlikely that any interesting security
    5921              :                      * violation could result from allowing access to the
    5922              :                      * expression stats, so we allow it anyway.  See similar
    5923              :                      * code in examine_simple_variable() for additional
    5924              :                      * comments.
    5925              :                      */
    5926          832 :                     vardata->acl_ok = all_rows_selectable(root,
    5927              :                                                           onerel->relid,
    5928              :                                                           NULL);
    5929              : 
    5930          832 :                     break;
    5931              :                 }
    5932              : 
    5933          651 :                 pos++;
    5934              :             }
    5935              :         }
    5936              :     }
    5937              : 
    5938       534712 :     bms_free(varnos);
    5939              : }
    5940              : 
    5941              : /*
    5942              :  * strip_all_phvs_deep
    5943              :  *      Deeply strip all PlaceHolderVars in an expression.
    5944              : 
    5945              :  * As a performance optimization, we first use a lightweight walker to check
    5946              :  * for the presence of any PlaceHolderVars.  The expensive mutator is invoked
    5947              :  * only if a PlaceHolderVar is found, avoiding unnecessary memory allocation
    5948              :  * and tree copying in the common case where no PlaceHolderVars are present.
    5949              :  */
    5950              : static Node *
    5951      1895011 : strip_all_phvs_deep(PlannerInfo *root, Node *node)
    5952              : {
    5953              :     /* If there are no PHVs anywhere, we needn't work hard */
    5954      1895011 :     if (root->glob->lastPHId == 0)
    5955      1877713 :         return node;
    5956              : 
    5957        17298 :     if (!contain_placeholder_walker(node, NULL))
    5958        15129 :         return node;
    5959         2169 :     return strip_all_phvs_mutator(node, NULL);
    5960              : }
    5961              : 
    5962              : /*
    5963              :  * contain_placeholder_walker
    5964              :  *      Lightweight walker to check if an expression contains any
    5965              :  *      PlaceHolderVars
    5966              :  */
    5967              : static bool
    5968        19597 : contain_placeholder_walker(Node *node, void *context)
    5969              : {
    5970        19597 :     if (node == NULL)
    5971          105 :         return false;
    5972        19492 :     if (IsA(node, PlaceHolderVar))
    5973         2169 :         return true;
    5974              : 
    5975        17323 :     return expression_tree_walker(node, contain_placeholder_walker, context);
    5976              : }
    5977              : 
    5978              : /*
    5979              :  * strip_all_phvs_mutator
    5980              :  *      Mutator to deeply strip all PlaceHolderVars
    5981              :  */
    5982              : static Node *
    5983         5847 : strip_all_phvs_mutator(Node *node, void *context)
    5984              : {
    5985         5847 :     if (node == NULL)
    5986           24 :         return NULL;
    5987         5823 :     if (IsA(node, PlaceHolderVar))
    5988              :     {
    5989              :         /* Strip it and recurse into its contained expression */
    5990         2244 :         PlaceHolderVar *phv = (PlaceHolderVar *) node;
    5991              : 
    5992         2244 :         return strip_all_phvs_mutator((Node *) phv->phexpr, context);
    5993              :     }
    5994              : 
    5995         3579 :     return expression_tree_mutator(node, strip_all_phvs_mutator, context);
    5996              : }
    5997              : 
    5998              : /*
    5999              :  * examine_simple_variable
    6000              :  *      Handle a simple Var for examine_variable
    6001              :  *
    6002              :  * This is split out as a subroutine so that we can recurse to deal with
    6003              :  * Vars referencing subqueries (either sub-SELECT-in-FROM or CTE style).
    6004              :  *
    6005              :  * We already filled in all the fields of *vardata except for the stats tuple.
    6006              :  */
    6007              : static void
    6008      1363492 : examine_simple_variable(PlannerInfo *root, Var *var,
    6009              :                         VariableStatData *vardata)
    6010              : {
    6011      1363492 :     RangeTblEntry *rte = root->simple_rte_array[var->varno];
    6012              : 
    6013              :     Assert(IsA(rte, RangeTblEntry));
    6014              : 
    6015      1363492 :     if (get_relation_stats_hook &&
    6016            0 :         (*get_relation_stats_hook) (root, rte, var->varattno, vardata))
    6017              :     {
    6018              :         /*
    6019              :          * The hook took control of acquiring a stats tuple.  If it did supply
    6020              :          * a tuple, it'd better have supplied a freefunc.
    6021              :          */
    6022            0 :         if (HeapTupleIsValid(vardata->statsTuple) &&
    6023            0 :             !vardata->freefunc)
    6024            0 :             elog(ERROR, "no function provided to release variable stats with");
    6025              :     }
    6026      1363492 :     else if (rte->rtekind == RTE_RELATION)
    6027              :     {
    6028              :         /*
    6029              :          * Plain table or parent of an inheritance appendrel, so look up the
    6030              :          * column in pg_statistic
    6031              :          */
    6032      1298329 :         vardata->statsTuple = SearchSysCache3(STATRELATTINH,
    6033              :                                               ObjectIdGetDatum(rte->relid),
    6034      1298329 :                                               Int16GetDatum(var->varattno),
    6035      1298329 :                                               BoolGetDatum(rte->inh));
    6036      1298329 :         vardata->freefunc = ReleaseSysCache;
    6037              : 
    6038      1298329 :         if (HeapTupleIsValid(vardata->statsTuple))
    6039              :         {
    6040              :             /*
    6041              :              * Test if user has permission to read all rows from this column.
    6042              :              *
    6043              :              * This requires that the user has the appropriate SELECT
    6044              :              * privileges and that there are no securityQuals from security
    6045              :              * barrier views or RLS policies.  If that's not the case, then we
    6046              :              * only permit leakproof functions to be passed pg_statistic data
    6047              :              * in vardata, otherwise the functions might reveal data that the
    6048              :              * user doesn't have permission to see --- see
    6049              :              * statistic_proc_security_check().
    6050              :              */
    6051       899537 :             vardata->acl_ok =
    6052       899537 :                 all_rows_selectable(root, var->varno,
    6053       899537 :                                     bms_make_singleton(var->varattno - FirstLowInvalidHeapAttributeNumber));
    6054              :         }
    6055              :         else
    6056              :         {
    6057              :             /* suppress any possible leakproofness checks later */
    6058       398792 :             vardata->acl_ok = true;
    6059              :         }
    6060              :     }
    6061        65163 :     else if ((rte->rtekind == RTE_SUBQUERY && !rte->inh) ||
    6062        58981 :              (rte->rtekind == RTE_CTE && !rte->self_reference))
    6063              :     {
    6064              :         /*
    6065              :          * Plain subquery (not one that was converted to an appendrel) or
    6066              :          * non-recursive CTE.  In either case, we can try to find out what the
    6067              :          * Var refers to within the subquery.  We skip this for appendrel and
    6068              :          * recursive-CTE cases because any column stats we did find would
    6069              :          * likely not be very relevant.
    6070              :          */
    6071              :         PlannerInfo *subroot;
    6072              :         Query      *subquery;
    6073              :         List       *subtlist;
    6074              :         TargetEntry *ste;
    6075              : 
    6076              :         /*
    6077              :          * Punt if it's a whole-row var rather than a plain column reference.
    6078              :          */
    6079         9889 :         if (var->varattno == InvalidAttrNumber)
    6080            0 :             return;
    6081              : 
    6082              :         /*
    6083              :          * Otherwise, find the subquery's planner subroot.
    6084              :          */
    6085         9889 :         if (rte->rtekind == RTE_SUBQUERY)
    6086              :         {
    6087              :             RelOptInfo *rel;
    6088              : 
    6089              :             /*
    6090              :              * Fetch RelOptInfo for subquery.  Note that we don't change the
    6091              :              * rel returned in vardata, since caller expects it to be a rel of
    6092              :              * the caller's query level.  Because we might already be
    6093              :              * recursing, we can't use that rel pointer either, but have to
    6094              :              * look up the Var's rel afresh.
    6095              :              */
    6096         6182 :             rel = find_base_rel(root, var->varno);
    6097              : 
    6098         6182 :             subroot = rel->subroot;
    6099              :         }
    6100              :         else
    6101              :         {
    6102              :             /* CTE case is more difficult */
    6103              :             PlannerInfo *cteroot;
    6104              :             Index       levelsup;
    6105              :             int         ndx;
    6106              :             int         plan_id;
    6107              :             ListCell   *lc;
    6108              : 
    6109              :             /*
    6110              :              * Find the referenced CTE, and locate the subroot previously made
    6111              :              * for it.
    6112              :              */
    6113         3707 :             levelsup = rte->ctelevelsup;
    6114         3707 :             cteroot = root;
    6115         6922 :             while (levelsup-- > 0)
    6116              :             {
    6117         3215 :                 cteroot = cteroot->parent_root;
    6118         3215 :                 if (!cteroot)   /* shouldn't happen */
    6119            0 :                     elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    6120              :             }
    6121              : 
    6122              :             /*
    6123              :              * Note: cte_plan_ids can be shorter than cteList, if we are still
    6124              :              * working on planning the CTEs (ie, this is a side-reference from
    6125              :              * another CTE).  So we mustn't use forboth here.
    6126              :              */
    6127         3707 :             ndx = 0;
    6128         4822 :             foreach(lc, cteroot->parse->cteList)
    6129              :             {
    6130         4822 :                 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
    6131              : 
    6132         4822 :                 if (strcmp(cte->ctename, rte->ctename) == 0)
    6133         3707 :                     break;
    6134         1115 :                 ndx++;
    6135              :             }
    6136         3707 :             if (lc == NULL)     /* shouldn't happen */
    6137            0 :                 elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
    6138         3707 :             if (ndx >= list_length(cteroot->cte_plan_ids))
    6139            0 :                 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
    6140         3707 :             plan_id = list_nth_int(cteroot->cte_plan_ids, ndx);
    6141         3707 :             if (plan_id <= 0)
    6142            0 :                 elog(ERROR, "no plan was made for CTE \"%s\"", rte->ctename);
    6143         3707 :             subroot = list_nth(root->glob->subroots, plan_id - 1);
    6144              :         }
    6145              : 
    6146              :         /* If the subquery hasn't been planned yet, we have to punt */
    6147         9889 :         if (subroot == NULL)
    6148            0 :             return;
    6149              :         Assert(IsA(subroot, PlannerInfo));
    6150              : 
    6151              :         /*
    6152              :          * We must use the subquery parsetree as mangled by the planner, not
    6153              :          * the raw version from the RTE, because we need a Var that will refer
    6154              :          * to the subroot's live RelOptInfos.  For instance, if any subquery
    6155              :          * pullup happened during planning, Vars in the targetlist might have
    6156              :          * gotten replaced, and we need to see the replacement expressions.
    6157              :          */
    6158         9889 :         subquery = subroot->parse;
    6159              :         Assert(IsA(subquery, Query));
    6160              : 
    6161              :         /*
    6162              :          * Punt if subquery uses set operations or grouping sets, as these
    6163              :          * will mash underlying columns' stats beyond recognition.  (Set ops
    6164              :          * are particularly nasty; if we forged ahead, we would return stats
    6165              :          * relevant to only the leftmost subselect...)  DISTINCT is also
    6166              :          * problematic, but we check that later because there is a possibility
    6167              :          * of learning something even with it.
    6168              :          */
    6169         9889 :         if (subquery->setOperations ||
    6170         8676 :             subquery->groupingSets)
    6171         1261 :             return;
    6172              : 
    6173              :         /* Get the subquery output expression referenced by the upper Var */
    6174         8628 :         if (subquery->returningList)
    6175          103 :             subtlist = subquery->returningList;
    6176              :         else
    6177         8525 :             subtlist = subquery->targetList;
    6178         8628 :         ste = get_tle_by_resno(subtlist, var->varattno);
    6179         8628 :         if (ste == NULL || ste->resjunk)
    6180            0 :             elog(ERROR, "subquery %s does not have attribute %d",
    6181              :                  rte->eref->aliasname, var->varattno);
    6182         8628 :         var = (Var *) ste->expr;
    6183              : 
    6184              :         /*
    6185              :          * If subquery uses DISTINCT, we can't make use of any stats for the
    6186              :          * variable ... but, if it's the only DISTINCT column, we are entitled
    6187              :          * to consider it unique.  We do the test this way so that it works
    6188              :          * for cases involving DISTINCT ON.
    6189              :          */
    6190         8628 :         if (subquery->distinctClause)
    6191              :         {
    6192          941 :             if (list_length(subquery->distinctClause) == 1 &&
    6193          319 :                 targetIsInSortList(ste, InvalidOid, subquery->distinctClause))
    6194          158 :                 vardata->isunique = true;
    6195              :             /* cannot go further */
    6196          622 :             return;
    6197              :         }
    6198              : 
    6199              :         /* The same idea as with DISTINCT clause works for a GROUP-BY too */
    6200         8006 :         if (subquery->groupClause)
    6201              :         {
    6202          564 :             if (list_length(subquery->groupClause) == 1 &&
    6203          237 :                 targetIsInSortList(ste, InvalidOid, subquery->groupClause))
    6204          181 :                 vardata->isunique = true;
    6205              :             /* cannot go further */
    6206          327 :             return;
    6207              :         }
    6208              : 
    6209              :         /*
    6210              :          * If the sub-query originated from a view with the security_barrier
    6211              :          * attribute, we must not look at the variable's statistics, though it
    6212              :          * seems all right to notice the existence of a DISTINCT clause. So
    6213              :          * stop here.
    6214              :          *
    6215              :          * This is probably a harsher restriction than necessary; it's
    6216              :          * certainly OK for the selectivity estimator (which is a C function,
    6217              :          * and therefore omnipotent anyway) to look at the statistics.  But
    6218              :          * many selectivity estimators will happily *invoke the operator
    6219              :          * function* to try to work out a good estimate - and that's not OK.
    6220              :          * So for now, don't dig down for stats.
    6221              :          */
    6222         7679 :         if (rte->security_barrier)
    6223         1431 :             return;
    6224              : 
    6225              :         /* Can only handle a simple Var of subquery's query level */
    6226         6248 :         if (var && IsA(var, Var) &&
    6227         3193 :             var->varlevelsup == 0)
    6228              :         {
    6229              :             /*
    6230              :              * OK, recurse into the subquery.  Note that the original setting
    6231              :              * of vardata->isunique (which will surely be false) is left
    6232              :              * unchanged in this situation.  That's what we want, since even
    6233              :              * if the underlying column is unique, the subquery may have
    6234              :              * joined to other tables in a way that creates duplicates.
    6235              :              */
    6236         3193 :             examine_simple_variable(subroot, var, vardata);
    6237              :         }
    6238              :     }
    6239              :     else
    6240              :     {
    6241              :         /*
    6242              :          * Otherwise, the Var comes from a FUNCTION or VALUES RTE.  (We won't
    6243              :          * see RTE_JOIN here because join alias Vars have already been
    6244              :          * flattened.)  There's not much we can do with function outputs, but
    6245              :          * maybe someday try to be smarter about VALUES.
    6246              :          */
    6247              :     }
    6248              : }
    6249              : 
    6250              : /*
    6251              :  * all_rows_selectable
    6252              :  *      Test whether the user has permission to select all rows from a given
    6253              :  *      relation.
    6254              :  *
    6255              :  * Inputs:
    6256              :  *  root: the planner info
    6257              :  *  varno: the index of the relation (assumed to be an RTE_RELATION)
    6258              :  *  varattnos: the attributes for which permission is required, or NULL if
    6259              :  *      whole-table access is required
    6260              :  *
    6261              :  * Returns true if the user has the required select permissions, and there are
    6262              :  * no securityQuals from security barrier views or RLS policies.
    6263              :  *
    6264              :  * Note that if the relation is an inheritance child relation, securityQuals
    6265              :  * and access permissions are checked against the inheritance root parent (the
    6266              :  * relation actually mentioned in the query) --- see the comments in
    6267              :  * expand_single_inheritance_child() for an explanation of why it has to be
    6268              :  * done this way.
    6269              :  *
    6270              :  * If varattnos is non-NULL, its attribute numbers should be offset by
    6271              :  * FirstLowInvalidHeapAttributeNumber so that system attributes can be
    6272              :  * checked.  If varattnos is NULL, only table-level SELECT privileges are
    6273              :  * checked, not any column-level privileges.
    6274              :  *
    6275              :  * Note: if the relation is accessed via a view, this function actually tests
    6276              :  * whether the view owner has permission to select from the relation.  To
    6277              :  * ensure that the current user has permission, it is also necessary to check
    6278              :  * that the current user has permission to select from the view, which we do
    6279              :  * at planner-startup --- see subquery_planner().
    6280              :  *
    6281              :  * This is exported so that other estimation functions can use it.
    6282              :  */
    6283              : bool
    6284       901986 : all_rows_selectable(PlannerInfo *root, Index varno, Bitmapset *varattnos)
    6285              : {
    6286       901986 :     RelOptInfo *rel = find_base_rel_noerr(root, varno);
    6287       901986 :     RangeTblEntry *rte = planner_rt_fetch(varno, root);
    6288              :     Oid         userid;
    6289              :     int         varattno;
    6290              : 
    6291              :     Assert(rte->rtekind == RTE_RELATION);
    6292              : 
    6293              :     /*
    6294              :      * Determine the user ID to use for privilege checks (either the current
    6295              :      * user or the view owner, if we're accessing the table via a view).
    6296              :      *
    6297              :      * Normally the relation will have an associated RelOptInfo from which we
    6298              :      * can find the userid, but it might not if it's a RETURNING Var for an
    6299              :      * INSERT target relation.  In that case use the RTEPermissionInfo
    6300              :      * associated with the RTE.
    6301              :      *
    6302              :      * If we navigate up to a parent relation, we keep using the same userid,
    6303              :      * since it's the same in all relations of a given inheritance tree.
    6304              :      */
    6305       901986 :     if (rel)
    6306       901965 :         userid = rel->userid;
    6307              :     else
    6308              :     {
    6309              :         RTEPermissionInfo *perminfo;
    6310              : 
    6311           21 :         perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
    6312           21 :         userid = perminfo->checkAsUser;
    6313              :     }
    6314       901986 :     if (!OidIsValid(userid))
    6315       796242 :         userid = GetUserId();
    6316              : 
    6317              :     /*
    6318              :      * Permissions and securityQuals must be checked on the table actually
    6319              :      * mentioned in the query, so if this is an inheritance child, navigate up
    6320              :      * to the inheritance root parent.  If the user can read the whole table
    6321              :      * or the required columns there, then they can read from the child table
    6322              :      * too.  For per-column checks, we must find out which of the root
    6323              :      * parent's attributes the child relation's attributes correspond to.
    6324              :      */
    6325       901986 :     if (root->append_rel_array != NULL)
    6326              :     {
    6327              :         AppendRelInfo *appinfo;
    6328              : 
    6329       116636 :         appinfo = root->append_rel_array[varno];
    6330              : 
    6331              :         /*
    6332              :          * Partitions are mapped to their immediate parent, not the root
    6333              :          * parent, so must be ready to walk up multiple AppendRelInfos.  But
    6334              :          * stop if we hit a parent that is not RTE_RELATION --- that's a
    6335              :          * flattened UNION ALL subquery, not an inheritance parent.
    6336              :          */
    6337       217522 :         while (appinfo &&
    6338       101072 :                planner_rt_fetch(appinfo->parent_relid,
    6339       101072 :                                 root)->rtekind == RTE_RELATION)
    6340              :         {
    6341       100886 :             Bitmapset  *parent_varattnos = NULL;
    6342              : 
    6343              :             /*
    6344              :              * For each child attribute, find the corresponding parent
    6345              :              * attribute.  In rare cases, the attribute may be local to the
    6346              :              * child table, in which case, we've got to live with having no
    6347              :              * access to this column.
    6348              :              */
    6349       100886 :             varattno = -1;
    6350       200347 :             while ((varattno = bms_next_member(varattnos, varattno)) >= 0)
    6351              :             {
    6352              :                 AttrNumber  attno;
    6353              :                 AttrNumber  parent_attno;
    6354              : 
    6355        99461 :                 attno = varattno + FirstLowInvalidHeapAttributeNumber;
    6356              : 
    6357        99461 :                 if (attno == InvalidAttrNumber)
    6358              :                 {
    6359              :                     /*
    6360              :                      * Whole-row reference, so must map each column of the
    6361              :                      * child to the parent table.
    6362              :                      */
    6363           18 :                     for (attno = 1; attno <= appinfo->num_child_cols; attno++)
    6364              :                     {
    6365           12 :                         parent_attno = appinfo->parent_colnos[attno - 1];
    6366           12 :                         if (parent_attno == 0)
    6367            0 :                             return false;   /* attr is local to child */
    6368              :                         parent_varattnos =
    6369           12 :                             bms_add_member(parent_varattnos,
    6370              :                                            parent_attno - FirstLowInvalidHeapAttributeNumber);
    6371              :                     }
    6372              :                 }
    6373              :                 else
    6374              :                 {
    6375        99455 :                     if (attno < 0)
    6376              :                     {
    6377              :                         /* System attnos are the same in all tables */
    6378            0 :                         parent_attno = attno;
    6379              :                     }
    6380              :                     else
    6381              :                     {
    6382        99455 :                         if (attno > appinfo->num_child_cols)
    6383            0 :                             return false;   /* safety check */
    6384        99455 :                         parent_attno = appinfo->parent_colnos[attno - 1];
    6385        99455 :                         if (parent_attno == 0)
    6386            0 :                             return false;   /* attr is local to child */
    6387              :                     }
    6388              :                     parent_varattnos =
    6389        99455 :                         bms_add_member(parent_varattnos,
    6390              :                                        parent_attno - FirstLowInvalidHeapAttributeNumber);
    6391              :                 }
    6392              :             }
    6393              : 
    6394              :             /* If the parent is itself a child, continue up */
    6395       100886 :             varno = appinfo->parent_relid;
    6396       100886 :             varattnos = parent_varattnos;
    6397       100886 :             appinfo = root->append_rel_array[varno];
    6398              :         }
    6399              : 
    6400              :         /* Perform the access check on this parent rel */
    6401       116636 :         rte = planner_rt_fetch(varno, root);
    6402              :         Assert(rte->rtekind == RTE_RELATION);
    6403              :     }
    6404              : 
    6405              :     /*
    6406              :      * For all rows to be accessible, there must be no securityQuals from
    6407              :      * security barrier views or RLS policies.
    6408              :      */
    6409       901986 :     if (rte->securityQuals != NIL)
    6410          414 :         return false;
    6411              : 
    6412              :     /*
    6413              :      * Test for table-level SELECT privilege.
    6414              :      *
    6415              :      * If varattnos is non-NULL, this is sufficient to give access to all
    6416              :      * requested attributes, even for a child table, since we have verified
    6417              :      * that all required child columns have matching parent columns.
    6418              :      *
    6419              :      * If varattnos is NULL (whole-table access requested), this doesn't
    6420              :      * necessarily guarantee that the user can read all columns of a child
    6421              :      * table, but we allow it anyway (see comments in examine_variable()) and
    6422              :      * don't bother checking any column privileges.
    6423              :      */
    6424       901572 :     if (pg_class_aclcheck(rte->relid, userid, ACL_SELECT) == ACLCHECK_OK)
    6425       901346 :         return true;
    6426              : 
    6427          226 :     if (varattnos == NULL)
    6428            6 :         return false;           /* whole-table access requested */
    6429              : 
    6430              :     /*
    6431              :      * Don't have table-level SELECT privilege, so check per-column
    6432              :      * privileges.
    6433              :      */
    6434          220 :     varattno = -1;
    6435          323 :     while ((varattno = bms_next_member(varattnos, varattno)) >= 0)
    6436              :     {
    6437          220 :         AttrNumber  attno = varattno + FirstLowInvalidHeapAttributeNumber;
    6438              : 
    6439          220 :         if (attno == InvalidAttrNumber)
    6440              :         {
    6441              :             /* Whole-row reference, so must have access to all columns */
    6442            3 :             if (pg_attribute_aclcheck_all(rte->relid, userid, ACL_SELECT,
    6443              :                                           ACLMASK_ALL) != ACLCHECK_OK)
    6444            3 :                 return false;
    6445              :         }
    6446              :         else
    6447              :         {
    6448          217 :             if (pg_attribute_aclcheck(rte->relid, attno, userid,
    6449              :                                       ACL_SELECT) != ACLCHECK_OK)
    6450          114 :                 return false;
    6451              :         }
    6452              :     }
    6453              : 
    6454              :     /* If we reach here, have all required column privileges */
    6455          103 :     return true;
    6456              : }
    6457              : 
    6458              : /*
    6459              :  * examine_indexcol_variable
    6460              :  *      Try to look up statistical data about an index column/expression.
    6461              :  *      Fill in a VariableStatData struct to describe the column.
    6462              :  *
    6463              :  * Inputs:
    6464              :  *  root: the planner info
    6465              :  *  index: the index whose column we're interested in
    6466              :  *  indexcol: 0-based index column number (subscripts index->indexkeys[])
    6467              :  *
    6468              :  * Outputs: *vardata is filled as follows:
    6469              :  *  var: the input expression (with any binary relabeling stripped, if
    6470              :  *      it is or contains a variable; but otherwise the type is preserved)
    6471              :  *  rel: RelOptInfo for table relation containing variable.
    6472              :  *  statsTuple: the pg_statistic entry for the variable, if one exists;
    6473              :  *      otherwise NULL.
    6474              :  *  freefunc: pointer to a function to release statsTuple with.
    6475              :  *
    6476              :  * Caller is responsible for doing ReleaseVariableStats() before exiting.
    6477              :  */
    6478              : static void
    6479       472177 : examine_indexcol_variable(PlannerInfo *root, IndexOptInfo *index,
    6480              :                           int indexcol, VariableStatData *vardata)
    6481              : {
    6482              :     AttrNumber  colnum;
    6483              :     Oid         relid;
    6484              : 
    6485       472177 :     if (index->indexkeys[indexcol] != 0)
    6486              :     {
    6487              :         /* Simple variable --- look to stats for the underlying table */
    6488       471070 :         RangeTblEntry *rte = planner_rt_fetch(index->rel->relid, root);
    6489              : 
    6490              :         Assert(rte->rtekind == RTE_RELATION);
    6491       471070 :         relid = rte->relid;
    6492              :         Assert(relid != InvalidOid);
    6493       471070 :         colnum = index->indexkeys[indexcol];
    6494       471070 :         vardata->rel = index->rel;
    6495              : 
    6496       471070 :         if (get_relation_stats_hook &&
    6497            0 :             (*get_relation_stats_hook) (root, rte, colnum, vardata))
    6498              :         {
    6499              :             /*
    6500              :              * The hook took control of acquiring a stats tuple.  If it did
    6501              :              * supply a tuple, it'd better have supplied a freefunc.
    6502              :              */
    6503            0 :             if (HeapTupleIsValid(vardata->statsTuple) &&
    6504            0 :                 !vardata->freefunc)
    6505            0 :                 elog(ERROR, "no function provided to release variable stats with");
    6506              :         }
    6507              :         else
    6508              :         {
    6509       471070 :             vardata->statsTuple = SearchSysCache3(STATRELATTINH,
    6510              :                                                   ObjectIdGetDatum(relid),
    6511              :                                                   Int16GetDatum(colnum),
    6512       471070 :                                                   BoolGetDatum(rte->inh));
    6513       471070 :             vardata->freefunc = ReleaseSysCache;
    6514              :         }
    6515              :     }
    6516              :     else
    6517              :     {
    6518              :         /* Expression --- maybe there are stats for the index itself */
    6519         1107 :         relid = index->indexoid;
    6520         1107 :         colnum = indexcol + 1;
    6521              : 
    6522         1107 :         if (get_index_stats_hook &&
    6523            0 :             (*get_index_stats_hook) (root, relid, colnum, vardata))
    6524              :         {
    6525              :             /*
    6526              :              * The hook took control of acquiring a stats tuple.  If it did
    6527              :              * supply a tuple, it'd better have supplied a freefunc.
    6528              :              */
    6529            0 :             if (HeapTupleIsValid(vardata->statsTuple) &&
    6530            0 :                 !vardata->freefunc)
    6531            0 :                 elog(ERROR, "no function provided to release variable stats with");
    6532              :         }
    6533              :         else
    6534              :         {
    6535         1107 :             vardata->statsTuple = SearchSysCache3(STATRELATTINH,
    6536              :                                                   ObjectIdGetDatum(relid),
    6537              :                                                   Int16GetDatum(colnum),
    6538              :                                                   BoolGetDatum(false));
    6539         1107 :             vardata->freefunc = ReleaseSysCache;
    6540              :         }
    6541              :     }
    6542       472177 : }
    6543              : 
    6544              : /*
    6545              :  * Check whether it is permitted to call func_oid passing some of the
    6546              :  * pg_statistic data in vardata.  We allow this if either of the following
    6547              :  * conditions is met: (1) the user has SELECT privileges on the table or
    6548              :  * column underlying the pg_statistic data and there are no securityQuals from
    6549              :  * security barrier views or RLS policies, or (2) the function is marked
    6550              :  * leakproof.
    6551              :  */
    6552              : bool
    6553       620298 : statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
    6554              : {
    6555       620298 :     if (vardata->acl_ok)
    6556       619373 :         return true;            /* have SELECT privs and no securityQuals */
    6557              : 
    6558          925 :     if (!OidIsValid(func_oid))
    6559            0 :         return false;
    6560              : 
    6561          925 :     if (get_func_leakproof(func_oid))
    6562          458 :         return true;
    6563              : 
    6564          467 :     ereport(DEBUG2,
    6565              :             (errmsg_internal("not using statistics because function \"%s\" is not leakproof",
    6566              :                              get_func_name(func_oid))));
    6567          467 :     return false;
    6568              : }
    6569              : 
    6570              : /*
    6571              :  * get_variable_numdistinct
    6572              :  *    Estimate the number of distinct values of a variable.
    6573              :  *
    6574              :  * vardata: results of examine_variable
    6575              :  * *isdefault: set to true if the result is a default rather than based on
    6576              :  * anything meaningful.
    6577              :  *
    6578              :  * NB: be careful to produce a positive integral result, since callers may
    6579              :  * compare the result to exact integer counts, or might divide by it.
    6580              :  */
    6581              : double
    6582       971664 : get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
    6583              : {
    6584              :     double      stadistinct;
    6585       971664 :     double      stanullfrac = 0.0;
    6586              :     double      ntuples;
    6587              : 
    6588       971664 :     *isdefault = false;
    6589              : 
    6590              :     /*
    6591              :      * Determine the stadistinct value to use.  There are cases where we can
    6592              :      * get an estimate even without a pg_statistic entry, or can get a better
    6593              :      * value than is in pg_statistic.  Grab stanullfrac too if we can find it
    6594              :      * (otherwise, assume no nulls, for lack of any better idea).
    6595              :      */
    6596       971664 :     if (HeapTupleIsValid(vardata->statsTuple))
    6597              :     {
    6598              :         /* Use the pg_statistic entry */
    6599              :         Form_pg_statistic stats;
    6600              : 
    6601       637352 :         stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
    6602       637352 :         stadistinct = stats->stadistinct;
    6603       637352 :         stanullfrac = stats->stanullfrac;
    6604              :     }
    6605       334312 :     else if (vardata->vartype == BOOLOID)
    6606              :     {
    6607              :         /*
    6608              :          * Special-case boolean columns: presumably, two distinct values.
    6609              :          *
    6610              :          * Are there any other datatypes we should wire in special estimates
    6611              :          * for?
    6612              :          */
    6613          480 :         stadistinct = 2.0;
    6614              :     }
    6615       333832 :     else if (vardata->rel && vardata->rel->rtekind == RTE_VALUES)
    6616              :     {
    6617              :         /*
    6618              :          * If the Var represents a column of a VALUES RTE, assume it's unique.
    6619              :          * This could of course be very wrong, but it should tend to be true
    6620              :          * in well-written queries.  We could consider examining the VALUES'
    6621              :          * contents to get some real statistics; but that only works if the
    6622              :          * entries are all constants, and it would be pretty expensive anyway.
    6623              :          */
    6624         1797 :         stadistinct = -1.0;     /* unique (and all non null) */
    6625              :     }
    6626              :     else
    6627              :     {
    6628              :         /*
    6629              :          * We don't keep statistics for system columns, but in some cases we
    6630              :          * can infer distinctness anyway.
    6631              :          */
    6632       332035 :         if (vardata->var && IsA(vardata->var, Var))
    6633              :         {
    6634       310326 :             switch (((Var *) vardata->var)->varattno)
    6635              :             {
    6636          612 :                 case SelfItemPointerAttributeNumber:
    6637          612 :                     stadistinct = -1.0; /* unique (and all non null) */
    6638          612 :                     break;
    6639        17543 :                 case TableOidAttributeNumber:
    6640        17543 :                     stadistinct = 1.0;  /* only 1 value */
    6641        17543 :                     break;
    6642       292171 :                 default:
    6643       292171 :                     stadistinct = 0.0;  /* means "unknown" */
    6644       292171 :                     break;
    6645              :             }
    6646              :         }
    6647              :         else
    6648        21709 :             stadistinct = 0.0;  /* means "unknown" */
    6649              : 
    6650              :         /*
    6651              :          * XXX consider using estimate_num_groups on expressions?
    6652              :          */
    6653              :     }
    6654              : 
    6655              :     /*
    6656              :      * If there is a unique index, DISTINCT or GROUP-BY clause for the
    6657              :      * variable, assume it is unique no matter what pg_statistic says; the
    6658              :      * statistics could be out of date, or we might have found a partial
    6659              :      * unique index that proves the var is unique for this query.  However,
    6660              :      * we'd better still believe the null-fraction statistic.
    6661              :      */
    6662       971664 :     if (vardata->isunique)
    6663       245838 :         stadistinct = -1.0 * (1.0 - stanullfrac);
    6664              : 
    6665              :     /*
    6666              :      * If we had an absolute estimate, use that.
    6667              :      */
    6668       971664 :     if (stadistinct > 0.0)
    6669       237545 :         return clamp_row_est(stadistinct);
    6670              : 
    6671              :     /*
    6672              :      * Otherwise we need to get the relation size; punt if not available.
    6673              :      */
    6674       734119 :     if (vardata->rel == NULL)
    6675              :     {
    6676          354 :         *isdefault = true;
    6677          354 :         return DEFAULT_NUM_DISTINCT;
    6678              :     }
    6679       733765 :     ntuples = vardata->rel->tuples;
    6680       733765 :     if (ntuples <= 0.0)
    6681              :     {
    6682        87935 :         *isdefault = true;
    6683        87935 :         return DEFAULT_NUM_DISTINCT;
    6684              :     }
    6685              : 
    6686              :     /*
    6687              :      * If we had a relative estimate, use that.
    6688              :      */
    6689       645830 :     if (stadistinct < 0.0)
    6690       451991 :         return clamp_row_est(-stadistinct * ntuples);
    6691              : 
    6692              :     /*
    6693              :      * With no data, estimate ndistinct = ntuples if the table is small, else
    6694              :      * use default.  We use DEFAULT_NUM_DISTINCT as the cutoff for "small" so
    6695              :      * that the behavior isn't discontinuous.
    6696              :      */
    6697       193839 :     if (ntuples < DEFAULT_NUM_DISTINCT)
    6698        92600 :         return clamp_row_est(ntuples);
    6699              : 
    6700       101239 :     *isdefault = true;
    6701       101239 :     return DEFAULT_NUM_DISTINCT;
    6702              : }
    6703              : 
    6704              : /*
    6705              :  * get_variable_range
    6706              :  *      Estimate the minimum and maximum value of the specified variable.
    6707              :  *      If successful, store values in *min and *max, and return true.
    6708              :  *      If no data available, return false.
    6709              :  *
    6710              :  * sortop is the "<" comparison operator to use.  This should generally
    6711              :  * be "<" not ">", as only the former is likely to be found in pg_statistic.
    6712              :  * The collation must be specified too.
    6713              :  */
    6714              : static bool
    6715       139088 : get_variable_range(PlannerInfo *root, VariableStatData *vardata,
    6716              :                    Oid sortop, Oid collation,
    6717              :                    Datum *min, Datum *max)
    6718              : {
    6719       139088 :     Datum       tmin = 0;
    6720       139088 :     Datum       tmax = 0;
    6721       139088 :     bool        have_data = false;
    6722              :     int16       typLen;
    6723              :     bool        typByVal;
    6724              :     Oid         opfuncoid;
    6725              :     FmgrInfo    opproc;
    6726              :     AttStatsSlot sslot;
    6727              : 
    6728              :     /*
    6729              :      * XXX It's very tempting to try to use the actual column min and max, if
    6730              :      * we can get them relatively-cheaply with an index probe.  However, since
    6731              :      * this function is called many times during join planning, that could
    6732              :      * have unpleasant effects on planning speed.  Need more investigation
    6733              :      * before enabling this.
    6734              :      */
    6735              : #ifdef NOT_USED
    6736              :     if (get_actual_variable_range(root, vardata, sortop, collation, min, max))
    6737              :         return true;
    6738              : #endif
    6739              : 
    6740       139088 :     if (!HeapTupleIsValid(vardata->statsTuple))
    6741              :     {
    6742              :         /* no stats available, so default result */
    6743        36508 :         return false;
    6744              :     }
    6745              : 
    6746              :     /*
    6747              :      * If we can't apply the sortop to the stats data, just fail.  In
    6748              :      * principle, if there's a histogram and no MCVs, we could return the
    6749              :      * histogram endpoints without ever applying the sortop ... but it's
    6750              :      * probably not worth trying, because whatever the caller wants to do with
    6751              :      * the endpoints would likely fail the security check too.
    6752              :      */
    6753       102580 :     if (!statistic_proc_security_check(vardata,
    6754       102580 :                                        (opfuncoid = get_opcode(sortop))))
    6755            0 :         return false;
    6756              : 
    6757       102580 :     opproc.fn_oid = InvalidOid; /* mark this as not looked up yet */
    6758              : 
    6759       102580 :     get_typlenbyval(vardata->atttype, &typLen, &typByVal);
    6760              : 
    6761              :     /*
    6762              :      * If there is a histogram with the ordering we want, grab the first and
    6763              :      * last values.
    6764              :      */
    6765       102580 :     if (get_attstatsslot(&sslot, vardata->statsTuple,
    6766              :                          STATISTIC_KIND_HISTOGRAM, sortop,
    6767              :                          ATTSTATSSLOT_VALUES))
    6768              :     {
    6769        65939 :         if (sslot.stacoll == collation && sslot.nvalues > 0)
    6770              :         {
    6771        65939 :             tmin = datumCopy(sslot.values[0], typByVal, typLen);
    6772        65939 :             tmax = datumCopy(sslot.values[sslot.nvalues - 1], typByVal, typLen);
    6773        65939 :             have_data = true;
    6774              :         }
    6775        65939 :         free_attstatsslot(&sslot);
    6776              :     }
    6777              : 
    6778              :     /*
    6779              :      * Otherwise, if there is a histogram with some other ordering, scan it
    6780              :      * and get the min and max values according to the ordering we want.  This
    6781              :      * of course may not find values that are really extremal according to our
    6782              :      * ordering, but it beats ignoring available data.
    6783              :      */
    6784       139221 :     if (!have_data &&
    6785        36641 :         get_attstatsslot(&sslot, vardata->statsTuple,
    6786              :                          STATISTIC_KIND_HISTOGRAM, InvalidOid,
    6787              :                          ATTSTATSSLOT_VALUES))
    6788              :     {
    6789            0 :         get_stats_slot_range(&sslot, opfuncoid, &opproc,
    6790              :                              collation, typLen, typByVal,
    6791              :                              &tmin, &tmax, &have_data);
    6792            0 :         free_attstatsslot(&sslot);
    6793              :     }
    6794              : 
    6795              :     /*
    6796              :      * If we have most-common-values info, look for extreme MCVs.  This is
    6797              :      * needed even if we also have a histogram, since the histogram excludes
    6798              :      * the MCVs.  However, if we *only* have MCVs and no histogram, we should
    6799              :      * be pretty wary of deciding that that is a full representation of the
    6800              :      * data.  Proceed only if the MCVs represent the whole table (to within
    6801              :      * roundoff error).
    6802              :      */
    6803       102580 :     if (get_attstatsslot(&sslot, vardata->statsTuple,
    6804              :                          STATISTIC_KIND_MCV, InvalidOid,
    6805       102580 :                          have_data ? ATTSTATSSLOT_VALUES :
    6806              :                          (ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS)))
    6807              :     {
    6808        56925 :         bool        use_mcvs = have_data;
    6809              : 
    6810        56925 :         if (!have_data)
    6811              :         {
    6812        35802 :             double      sumcommon = 0.0;
    6813              :             double      nullfrac;
    6814              :             int         i;
    6815              : 
    6816       280356 :             for (i = 0; i < sslot.nnumbers; i++)
    6817       244554 :                 sumcommon += sslot.numbers[i];
    6818        35802 :             nullfrac = ((Form_pg_statistic) GETSTRUCT(vardata->statsTuple))->stanullfrac;
    6819        35802 :             if (sumcommon + nullfrac > 0.99999)
    6820        35692 :                 use_mcvs = true;
    6821              :         }
    6822              : 
    6823        56925 :         if (use_mcvs)
    6824        56815 :             get_stats_slot_range(&sslot, opfuncoid, &opproc,
    6825              :                                  collation, typLen, typByVal,
    6826              :                                  &tmin, &tmax, &have_data);
    6827        56925 :         free_attstatsslot(&sslot);
    6828              :     }
    6829              : 
    6830       102580 :     *min = tmin;
    6831       102580 :     *max = tmax;
    6832       102580 :     return have_data;
    6833              : }
    6834              : 
    6835              : /*
    6836              :  * get_stats_slot_range: scan sslot for min/max values
    6837              :  *
    6838              :  * Subroutine for get_variable_range: update min/max/have_data according
    6839              :  * to what we find in the statistics array.
    6840              :  */
    6841              : static void
    6842        56815 : get_stats_slot_range(AttStatsSlot *sslot, Oid opfuncoid, FmgrInfo *opproc,
    6843              :                      Oid collation, int16 typLen, bool typByVal,
    6844              :                      Datum *min, Datum *max, bool *p_have_data)
    6845              : {
    6846        56815 :     Datum       tmin = *min;
    6847        56815 :     Datum       tmax = *max;
    6848        56815 :     bool        have_data = *p_have_data;
    6849        56815 :     bool        found_tmin = false;
    6850        56815 :     bool        found_tmax = false;
    6851              : 
    6852              :     /* Look up the comparison function, if we didn't already do so */
    6853        56815 :     if (opproc->fn_oid != opfuncoid)
    6854        56815 :         fmgr_info(opfuncoid, opproc);
    6855              : 
    6856              :     /* Scan all the slot's values */
    6857      1418780 :     for (int i = 0; i < sslot->nvalues; i++)
    6858              :     {
    6859      1361965 :         if (!have_data)
    6860              :         {
    6861        35692 :             tmin = tmax = sslot->values[i];
    6862        35692 :             found_tmin = found_tmax = true;
    6863        35692 :             *p_have_data = have_data = true;
    6864        35692 :             continue;
    6865              :         }
    6866      1326273 :         if (DatumGetBool(FunctionCall2Coll(opproc,
    6867              :                                            collation,
    6868      1326273 :                                            sslot->values[i], tmin)))
    6869              :         {
    6870        33553 :             tmin = sslot->values[i];
    6871        33553 :             found_tmin = true;
    6872              :         }
    6873      1326273 :         if (DatumGetBool(FunctionCall2Coll(opproc,
    6874              :                                            collation,
    6875      1326273 :                                            tmax, sslot->values[i])))
    6876              :         {
    6877       133427 :             tmax = sslot->values[i];
    6878       133427 :             found_tmax = true;
    6879              :         }
    6880              :     }
    6881              : 
    6882              :     /*
    6883              :      * Copy the slot's values, if we found new extreme values.
    6884              :      */
    6885        56815 :     if (found_tmin)
    6886        48183 :         *min = datumCopy(tmin, typByVal, typLen);
    6887        56815 :     if (found_tmax)
    6888        37890 :         *max = datumCopy(tmax, typByVal, typLen);
    6889        56815 : }
    6890              : 
    6891              : 
    6892              : /*
    6893              :  * get_actual_variable_range
    6894              :  *      Attempt to identify the current *actual* minimum and/or maximum
    6895              :  *      of the specified variable, by looking for a suitable btree index
    6896              :  *      and fetching its low and/or high values.
    6897              :  *      If successful, store values in *min and *max, and return true.
    6898              :  *      (Either pointer can be NULL if that endpoint isn't needed.)
    6899              :  *      If unsuccessful, return false.
    6900              :  *
    6901              :  * sortop is the "<" comparison operator to use.
    6902              :  * collation is the required collation.
    6903              :  */
    6904              : static bool
    6905       101745 : get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
    6906              :                           Oid sortop, Oid collation,
    6907              :                           Datum *min, Datum *max)
    6908              : {
    6909       101745 :     bool        have_data = false;
    6910       101745 :     RelOptInfo *rel = vardata->rel;
    6911              :     RangeTblEntry *rte;
    6912              :     ListCell   *lc;
    6913              : 
    6914              :     /* No hope if no relation or it doesn't have indexes */
    6915       101745 :     if (rel == NULL || rel->indexlist == NIL)
    6916         6910 :         return false;
    6917              :     /* If it has indexes it must be a plain relation */
    6918        94835 :     rte = root->simple_rte_array[rel->relid];
    6919              :     Assert(rte->rtekind == RTE_RELATION);
    6920              : 
    6921              :     /* ignore partitioned tables.  Any indexes here are not real indexes */
    6922        94835 :     if (rte->relkind == RELKIND_PARTITIONED_TABLE)
    6923          378 :         return false;
    6924              : 
    6925              :     /* Search through the indexes to see if any match our problem */
    6926       184508 :     foreach(lc, rel->indexlist)
    6927              :     {
    6928       157892 :         IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
    6929              :         ScanDirection indexscandir;
    6930              :         StrategyNumber strategy;
    6931              : 
    6932              :         /* Ignore non-ordering indexes */
    6933       157892 :         if (index->sortopfamily == NULL)
    6934            0 :             continue;
    6935              : 
    6936              :         /*
    6937              :          * Ignore partial indexes --- we only want stats that cover the entire
    6938              :          * relation.
    6939              :          */
    6940       157892 :         if (index->indpred != NIL)
    6941          144 :             continue;
    6942              : 
    6943              :         /*
    6944              :          * The index list might include hypothetical indexes inserted by a
    6945              :          * get_relation_info hook --- don't try to access them.
    6946              :          */
    6947       157748 :         if (index->hypothetical)
    6948            0 :             continue;
    6949              : 
    6950              :         /*
    6951              :          * get_actual_variable_endpoint uses the index-only-scan machinery, so
    6952              :          * ignore indexes that can't use it on their first column.
    6953              :          */
    6954       157748 :         if (!index->canreturn[0])
    6955            0 :             continue;
    6956              : 
    6957              :         /*
    6958              :          * The first index column must match the desired variable, sortop, and
    6959              :          * collation --- but we can use a descending-order index.
    6960              :          */
    6961       157748 :         if (collation != index->indexcollations[0])
    6962        20556 :             continue;           /* test first 'cause it's cheapest */
    6963       137192 :         if (!match_index_to_operand(vardata->var, 0, index))
    6964        69351 :             continue;
    6965        67841 :         strategy = get_op_opfamily_strategy(sortop, index->sortopfamily[0]);
    6966        67841 :         switch (IndexAmTranslateStrategy(strategy, index->relam, index->sortopfamily[0], true))
    6967              :         {
    6968        67841 :             case COMPARE_LT:
    6969        67841 :                 if (index->reverse_sort[0])
    6970            0 :                     indexscandir = BackwardScanDirection;
    6971              :                 else
    6972        67841 :                     indexscandir = ForwardScanDirection;
    6973        67841 :                 break;
    6974            0 :             case COMPARE_GT:
    6975            0 :                 if (index->reverse_sort[0])
    6976            0 :                     indexscandir = ForwardScanDirection;
    6977              :                 else
    6978            0 :                     indexscandir = BackwardScanDirection;
    6979            0 :                 break;
    6980            0 :             default:
    6981              :                 /* index doesn't match the sortop */
    6982            0 :                 continue;
    6983              :         }
    6984              : 
    6985              :         /*
    6986              :          * Found a suitable index to extract data from.  Set up some data that
    6987              :          * can be used by both invocations of get_actual_variable_endpoint.
    6988              :          */
    6989              :         {
    6990              :             MemoryContext tmpcontext;
    6991              :             MemoryContext oldcontext;
    6992              :             Relation    heapRel;
    6993              :             Relation    indexRel;
    6994              :             TupleTableSlot *slot;
    6995              :             int16       typLen;
    6996              :             bool        typByVal;
    6997              :             ScanKeyData scankeys[1];
    6998              : 
    6999              :             /* Make sure any cruft gets recycled when we're done */
    7000        67841 :             tmpcontext = AllocSetContextCreate(CurrentMemoryContext,
    7001              :                                                "get_actual_variable_range workspace",
    7002              :                                                ALLOCSET_DEFAULT_SIZES);
    7003        67841 :             oldcontext = MemoryContextSwitchTo(tmpcontext);
    7004              : 
    7005              :             /*
    7006              :              * Open the table and index so we can read from them.  We should
    7007              :              * already have some type of lock on each.
    7008              :              */
    7009        67841 :             heapRel = table_open(rte->relid, NoLock);
    7010        67841 :             indexRel = index_open(index->indexoid, NoLock);
    7011              : 
    7012              :             /* build some stuff needed for indexscan execution */
    7013        67841 :             slot = table_slot_create(heapRel, NULL);
    7014        67841 :             get_typlenbyval(vardata->atttype, &typLen, &typByVal);
    7015              : 
    7016              :             /* set up an IS NOT NULL scan key so that we ignore nulls */
    7017        67841 :             ScanKeyEntryInitialize(&scankeys[0],
    7018              :                                    SK_ISNULL | SK_SEARCHNOTNULL,
    7019              :                                    1,   /* index col to scan */
    7020              :                                    InvalidStrategy, /* no strategy */
    7021              :                                    InvalidOid,  /* no strategy subtype */
    7022              :                                    InvalidOid,  /* no collation */
    7023              :                                    InvalidOid,  /* no reg proc for this */
    7024              :                                    (Datum) 0);  /* constant */
    7025              : 
    7026              :             /* If min is requested ... */
    7027        67841 :             if (min)
    7028              :             {
    7029        38133 :                 have_data = get_actual_variable_endpoint(heapRel,
    7030              :                                                          indexRel,
    7031              :                                                          indexscandir,
    7032              :                                                          scankeys,
    7033              :                                                          typLen,
    7034              :                                                          typByVal,
    7035              :                                                          slot,
    7036              :                                                          oldcontext,
    7037              :                                                          min);
    7038              :             }
    7039              :             else
    7040              :             {
    7041              :                 /* If min not requested, still want to fetch max */
    7042        29708 :                 have_data = true;
    7043              :             }
    7044              : 
    7045              :             /* If max is requested, and we didn't already fail ... */
    7046        67841 :             if (max && have_data)
    7047              :             {
    7048              :                 /* scan in the opposite direction; all else is the same */
    7049        30774 :                 have_data = get_actual_variable_endpoint(heapRel,
    7050              :                                                          indexRel,
    7051        30774 :                                                          -indexscandir,
    7052              :                                                          scankeys,
    7053              :                                                          typLen,
    7054              :                                                          typByVal,
    7055              :                                                          slot,
    7056              :                                                          oldcontext,
    7057              :                                                          max);
    7058              :             }
    7059              : 
    7060              :             /* Clean everything up */
    7061        67841 :             ExecDropSingleTupleTableSlot(slot);
    7062              : 
    7063        67841 :             index_close(indexRel, NoLock);
    7064        67841 :             table_close(heapRel, NoLock);
    7065              : 
    7066        67841 :             MemoryContextSwitchTo(oldcontext);
    7067        67841 :             MemoryContextDelete(tmpcontext);
    7068              : 
    7069              :             /* And we're done */
    7070        67841 :             break;
    7071              :         }
    7072              :     }
    7073              : 
    7074        94457 :     return have_data;
    7075              : }
    7076              : 
    7077              : /*
    7078              :  * Get one endpoint datum (min or max depending on indexscandir) from the
    7079              :  * specified index.  Return true if successful, false if not.
    7080              :  * On success, endpoint value is stored to *endpointDatum (and copied into
    7081              :  * outercontext).
    7082              :  *
    7083              :  * scankeys is a 1-element scankey array set up to reject nulls.
    7084              :  * typLen/typByVal describe the datatype of the index's first column.
    7085              :  * tableslot is a slot suitable to hold table tuples, in case we need
    7086              :  * to probe the heap.
    7087              :  * (We could compute these values locally, but that would mean computing them
    7088              :  * twice when get_actual_variable_range needs both the min and the max.)
    7089              :  *
    7090              :  * Failure occurs either when the index is empty, or we decide that it's
    7091              :  * taking too long to find a suitable tuple.
    7092              :  */
    7093              : static bool
    7094        68907 : get_actual_variable_endpoint(Relation heapRel,
    7095              :                              Relation indexRel,
    7096              :                              ScanDirection indexscandir,
    7097              :                              ScanKey scankeys,
    7098              :                              int16 typLen,
    7099              :                              bool typByVal,
    7100              :                              TupleTableSlot *tableslot,
    7101              :                              MemoryContext outercontext,
    7102              :                              Datum *endpointDatum)
    7103              : {
    7104        68907 :     bool        have_data = false;
    7105              :     SnapshotData SnapshotNonVacuumable;
    7106              :     IndexScanDesc index_scan;
    7107        68907 :     Buffer      vmbuffer = InvalidBuffer;
    7108        68907 :     BlockNumber last_heap_block = InvalidBlockNumber;
    7109        68907 :     int         n_visited_heap_pages = 0;
    7110              :     ItemPointer tid;
    7111              :     Datum       values[INDEX_MAX_KEYS];
    7112              :     bool        isnull[INDEX_MAX_KEYS];
    7113              :     MemoryContext oldcontext;
    7114              : 
    7115              :     /*
    7116              :      * We use the index-only-scan machinery for this.  With mostly-static
    7117              :      * tables that's a win because it avoids a heap visit.  It's also a win
    7118              :      * for dynamic data, but the reason is less obvious; read on for details.
    7119              :      *
    7120              :      * In principle, we should scan the index with our current active
    7121              :      * snapshot, which is the best approximation we've got to what the query
    7122              :      * will see when executed.  But that won't be exact if a new snap is taken
    7123              :      * before running the query, and it can be very expensive if a lot of
    7124              :      * recently-dead or uncommitted rows exist at the beginning or end of the
    7125              :      * index (because we'll laboriously fetch each one and reject it).
    7126              :      * Instead, we use SnapshotNonVacuumable.  That will accept recently-dead
    7127              :      * and uncommitted rows as well as normal visible rows.  On the other
    7128              :      * hand, it will reject known-dead rows, and thus not give a bogus answer
    7129              :      * when the extreme value has been deleted (unless the deletion was quite
    7130              :      * recent); that case motivates not using SnapshotAny here.
    7131              :      *
    7132              :      * A crucial point here is that SnapshotNonVacuumable, with
    7133              :      * GlobalVisTestFor(heapRel) as horizon, yields the inverse of the
    7134              :      * condition that the indexscan will use to decide that index entries are
    7135              :      * killable (see heap_hot_search_buffer()).  Therefore, if the snapshot
    7136              :      * rejects a tuple (or more precisely, all tuples of a HOT chain) and we
    7137              :      * have to continue scanning past it, we know that the indexscan will mark
    7138              :      * that index entry killed.  That means that the next
    7139              :      * get_actual_variable_endpoint() call will not have to re-consider that
    7140              :      * index entry.  In this way we avoid repetitive work when this function
    7141              :      * is used a lot during planning.
    7142              :      *
    7143              :      * But using SnapshotNonVacuumable creates a hazard of its own.  In a
    7144              :      * recently-created index, some index entries may point at "broken" HOT
    7145              :      * chains in which not all the tuple versions contain data matching the
    7146              :      * index entry.  The live tuple version(s) certainly do match the index,
    7147              :      * but SnapshotNonVacuumable can accept recently-dead tuple versions that
    7148              :      * don't match.  Hence, if we took data from the selected heap tuple, we
    7149              :      * might get a bogus answer that's not close to the index extremal value,
    7150              :      * or could even be NULL.  We avoid this hazard because we take the data
    7151              :      * from the index entry not the heap.
    7152              :      *
    7153              :      * Despite all this care, there are situations where we might find many
    7154              :      * non-visible tuples near the end of the index.  We don't want to expend
    7155              :      * a huge amount of time here, so we give up once we've read too many heap
    7156              :      * pages.  When we fail for that reason, the caller will end up using
    7157              :      * whatever extremal value is recorded in pg_statistic.
    7158              :      */
    7159        68907 :     InitNonVacuumableSnapshot(SnapshotNonVacuumable,
    7160              :                               GlobalVisTestFor(heapRel));
    7161              : 
    7162        68907 :     index_scan = index_beginscan(heapRel, indexRel,
    7163              :                                  &SnapshotNonVacuumable, NULL,
    7164              :                                  1, 0);
    7165              :     /* Set it up for index-only scan */
    7166        68907 :     index_scan->xs_want_itup = true;
    7167        68907 :     index_rescan(index_scan, scankeys, 1, NULL, 0);
    7168              : 
    7169              :     /* Fetch first/next tuple in specified direction */
    7170        86030 :     while ((tid = index_getnext_tid(index_scan, indexscandir)) != NULL)
    7171              :     {
    7172        86030 :         BlockNumber block = ItemPointerGetBlockNumber(tid);
    7173              : 
    7174        86030 :         if (!VM_ALL_VISIBLE(heapRel,
    7175              :                             block,
    7176              :                             &vmbuffer))
    7177              :         {
    7178              :             /* Rats, we have to visit the heap to check visibility */
    7179        59421 :             if (!index_fetch_heap(index_scan, tableslot))
    7180              :             {
    7181              :                 /*
    7182              :                  * No visible tuple for this index entry, so we need to
    7183              :                  * advance to the next entry.  Before doing so, count heap
    7184              :                  * page fetches and give up if we've done too many.
    7185              :                  *
    7186              :                  * We don't charge a page fetch if this is the same heap page
    7187              :                  * as the previous tuple.  This is on the conservative side,
    7188              :                  * since other recently-accessed pages are probably still in
    7189              :                  * buffers too; but it's good enough for this heuristic.
    7190              :                  */
    7191              : #define VISITED_PAGES_LIMIT 100
    7192              : 
    7193        17123 :                 if (block != last_heap_block)
    7194              :                 {
    7195         1478 :                     last_heap_block = block;
    7196         1478 :                     n_visited_heap_pages++;
    7197         1478 :                     if (n_visited_heap_pages > VISITED_PAGES_LIMIT)
    7198            0 :                         break;
    7199              :                 }
    7200              : 
    7201        17123 :                 continue;       /* no visible tuple, try next index entry */
    7202              :             }
    7203              : 
    7204              :             /* We don't actually need the heap tuple for anything */
    7205        42298 :             ExecClearTuple(tableslot);
    7206              : 
    7207              :             /*
    7208              :              * We don't care whether there's more than one visible tuple in
    7209              :              * the HOT chain; if any are visible, that's good enough.
    7210              :              */
    7211              :         }
    7212              : 
    7213              :         /*
    7214              :          * We expect that the index will return data in IndexTuple not
    7215              :          * HeapTuple format.
    7216              :          */
    7217        68907 :         if (!index_scan->xs_itup)
    7218            0 :             elog(ERROR, "no data returned for index-only scan");
    7219              : 
    7220              :         /*
    7221              :          * We do not yet support recheck here.
    7222              :          */
    7223        68907 :         if (index_scan->xs_recheck)
    7224            0 :             break;
    7225              : 
    7226              :         /* OK to deconstruct the index tuple */
    7227        68907 :         index_deform_tuple(index_scan->xs_itup,
    7228              :                            index_scan->xs_itupdesc,
    7229              :                            values, isnull);
    7230              : 
    7231              :         /* Shouldn't have got a null, but be careful */
    7232        68907 :         if (isnull[0])
    7233            0 :             elog(ERROR, "found unexpected null value in index \"%s\"",
    7234              :                  RelationGetRelationName(indexRel));
    7235              : 
    7236              :         /* Copy the index column value out to caller's context */
    7237        68907 :         oldcontext = MemoryContextSwitchTo(outercontext);
    7238        68907 :         *endpointDatum = datumCopy(values[0], typByVal, typLen);
    7239        68907 :         MemoryContextSwitchTo(oldcontext);
    7240        68907 :         have_data = true;
    7241        68907 :         break;
    7242              :     }
    7243              : 
    7244        68907 :     if (vmbuffer != InvalidBuffer)
    7245        62528 :         ReleaseBuffer(vmbuffer);
    7246        68907 :     index_endscan(index_scan);
    7247              : 
    7248        68907 :     return have_data;
    7249              : }
    7250              : 
    7251              : /*
    7252              :  * find_join_input_rel
    7253              :  *      Look up the input relation for a join.
    7254              :  *
    7255              :  * We assume that the input relation's RelOptInfo must have been constructed
    7256              :  * already.
    7257              :  */
    7258              : static RelOptInfo *
    7259         7250 : find_join_input_rel(PlannerInfo *root, Relids relids)
    7260              : {
    7261         7250 :     RelOptInfo *rel = NULL;
    7262              : 
    7263         7250 :     if (!bms_is_empty(relids))
    7264              :     {
    7265              :         int         relid;
    7266              : 
    7267         7250 :         if (bms_get_singleton_member(relids, &relid))
    7268         7089 :             rel = find_base_rel(root, relid);
    7269              :         else
    7270          161 :             rel = find_join_rel(root, relids);
    7271              :     }
    7272              : 
    7273         7250 :     if (rel == NULL)
    7274            0 :         elog(ERROR, "could not find RelOptInfo for given relids");
    7275              : 
    7276         7250 :     return rel;
    7277              : }
    7278              : 
    7279              : 
    7280              : /*-------------------------------------------------------------------------
    7281              :  *
    7282              :  * Index cost estimation functions
    7283              :  *
    7284              :  *-------------------------------------------------------------------------
    7285              :  */
    7286              : 
    7287              : /*
    7288              :  * Extract the actual indexquals (as RestrictInfos) from an IndexClause list
    7289              :  */
    7290              : List *
    7291       480599 : get_quals_from_indexclauses(List *indexclauses)
    7292              : {
    7293       480599 :     List       *result = NIL;
    7294              :     ListCell   *lc;
    7295              : 
    7296       842452 :     foreach(lc, indexclauses)
    7297              :     {
    7298       361853 :         IndexClause *iclause = lfirst_node(IndexClause, lc);
    7299              :         ListCell   *lc2;
    7300              : 
    7301       725171 :         foreach(lc2, iclause->indexquals)
    7302              :         {
    7303       363318 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
    7304              : 
    7305       363318 :             result = lappend(result, rinfo);
    7306              :         }
    7307              :     }
    7308       480599 :     return result;
    7309              : }
    7310              : 
    7311              : /*
    7312              :  * Compute the total evaluation cost of the comparison operands in a list
    7313              :  * of index qual expressions.  Since we know these will be evaluated just
    7314              :  * once per scan, there's no need to distinguish startup from per-row cost.
    7315              :  *
    7316              :  * This can be used either on the result of get_quals_from_indexclauses(),
    7317              :  * or directly on an indexorderbys list.  In both cases, we expect that the
    7318              :  * index key expression is on the left side of binary clauses.
    7319              :  */
    7320              : Cost
    7321       954695 : index_other_operands_eval_cost(PlannerInfo *root, List *indexquals)
    7322              : {
    7323       954695 :     Cost        qual_arg_cost = 0;
    7324              :     ListCell   *lc;
    7325              : 
    7326      1318244 :     foreach(lc, indexquals)
    7327              :     {
    7328       363549 :         Expr       *clause = (Expr *) lfirst(lc);
    7329              :         Node       *other_operand;
    7330              :         QualCost    index_qual_cost;
    7331              : 
    7332              :         /*
    7333              :          * Index quals will have RestrictInfos, indexorderbys won't.  Look
    7334              :          * through RestrictInfo if present.
    7335              :          */
    7336       363549 :         if (IsA(clause, RestrictInfo))
    7337       363312 :             clause = ((RestrictInfo *) clause)->clause;
    7338              : 
    7339       363549 :         if (IsA(clause, OpExpr))
    7340              :         {
    7341       353539 :             OpExpr     *op = (OpExpr *) clause;
    7342              : 
    7343       353539 :             other_operand = (Node *) lsecond(op->args);
    7344              :         }
    7345        10010 :         else if (IsA(clause, RowCompareExpr))
    7346              :         {
    7347          198 :             RowCompareExpr *rc = (RowCompareExpr *) clause;
    7348              : 
    7349          198 :             other_operand = (Node *) rc->rargs;
    7350              :         }
    7351         9812 :         else if (IsA(clause, ScalarArrayOpExpr))
    7352              :         {
    7353         8349 :             ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
    7354              : 
    7355         8349 :             other_operand = (Node *) lsecond(saop->args);
    7356              :         }
    7357         1463 :         else if (IsA(clause, NullTest))
    7358              :         {
    7359         1463 :             other_operand = NULL;
    7360              :         }
    7361              :         else
    7362              :         {
    7363            0 :             elog(ERROR, "unsupported indexqual type: %d",
    7364              :                  (int) nodeTag(clause));
    7365              :             other_operand = NULL;   /* keep compiler quiet */
    7366              :         }
    7367              : 
    7368       363549 :         cost_qual_eval_node(&index_qual_cost, other_operand, root);
    7369       363549 :         qual_arg_cost += index_qual_cost.startup + index_qual_cost.per_tuple;
    7370              :     }
    7371       954695 :     return qual_arg_cost;
    7372              : }
    7373              : 
    7374              : void
    7375       474102 : genericcostestimate(PlannerInfo *root,
    7376              :                     IndexPath *path,
    7377              :                     double loop_count,
    7378              :                     GenericCosts *costs)
    7379              : {
    7380       474102 :     IndexOptInfo *index = path->indexinfo;
    7381       474102 :     List       *indexQuals = get_quals_from_indexclauses(path->indexclauses);
    7382       474102 :     List       *indexOrderBys = path->indexorderbys;
    7383              :     Cost        indexStartupCost;
    7384              :     Cost        indexTotalCost;
    7385              :     Selectivity indexSelectivity;
    7386              :     double      indexCorrelation;
    7387              :     double      numIndexPages;
    7388              :     double      numIndexTuples;
    7389              :     double      spc_random_page_cost;
    7390              :     double      num_sa_scans;
    7391              :     double      num_outer_scans;
    7392              :     double      num_scans;
    7393              :     double      qual_op_cost;
    7394              :     double      qual_arg_cost;
    7395              :     List       *selectivityQuals;
    7396              :     ListCell   *l;
    7397              : 
    7398              :     /*
    7399              :      * If the index is partial, AND the index predicate with the explicitly
    7400              :      * given indexquals to produce a more accurate idea of the index
    7401              :      * selectivity.
    7402              :      */
    7403       474102 :     selectivityQuals = add_predicate_to_index_quals(index, indexQuals);
    7404              : 
    7405              :     /*
    7406              :      * If caller didn't give us an estimate for ScalarArrayOpExpr index scans,
    7407              :      * just assume that the number of index descents is the number of distinct
    7408              :      * combinations of array elements from all of the scan's SAOP clauses.
    7409              :      */
    7410       474102 :     num_sa_scans = costs->num_sa_scans;
    7411       474102 :     if (num_sa_scans < 1)
    7412              :     {
    7413         3960 :         num_sa_scans = 1;
    7414         8312 :         foreach(l, indexQuals)
    7415              :         {
    7416         4352 :             RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
    7417              : 
    7418         4352 :             if (IsA(rinfo->clause, ScalarArrayOpExpr))
    7419              :             {
    7420           13 :                 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) rinfo->clause;
    7421           13 :                 double      alength = estimate_array_length(root, lsecond(saop->args));
    7422              : 
    7423           13 :                 if (alength > 1)
    7424           13 :                     num_sa_scans *= alength;
    7425              :             }
    7426              :         }
    7427              :     }
    7428              : 
    7429              :     /* Estimate the fraction of main-table tuples that will be visited */
    7430       474102 :     indexSelectivity = clauselist_selectivity(root, selectivityQuals,
    7431       474102 :                                               index->rel->relid,
    7432              :                                               JOIN_INNER,
    7433              :                                               NULL);
    7434              : 
    7435              :     /*
    7436              :      * If caller didn't give us an estimate, estimate the number of index
    7437              :      * tuples that will be visited.  We do it in this rather peculiar-looking
    7438              :      * way in order to get the right answer for partial indexes.
    7439              :      */
    7440       474102 :     numIndexTuples = costs->numIndexTuples;
    7441       474102 :     if (numIndexTuples <= 0.0)
    7442              :     {
    7443        61460 :         numIndexTuples = indexSelectivity * index->rel->tuples;
    7444              : 
    7445              :         /*
    7446              :          * The above calculation counts all the tuples visited across all
    7447              :          * scans induced by ScalarArrayOpExpr nodes.  We want to consider the
    7448              :          * average per-indexscan number, so adjust.  This is a handy place to
    7449              :          * round to integer, too.  (If caller supplied tuple estimate, it's
    7450              :          * responsible for handling these considerations.)
    7451              :          */
    7452        61460 :         numIndexTuples = rint(numIndexTuples / num_sa_scans);
    7453              :     }
    7454              : 
    7455              :     /*
    7456              :      * We can bound the number of tuples by the index size in any case. Also,
    7457              :      * always estimate at least one tuple is touched, even when
    7458              :      * indexSelectivity estimate is tiny.
    7459              :      */
    7460       474102 :     if (numIndexTuples > index->tuples)
    7461         5653 :         numIndexTuples = index->tuples;
    7462       474102 :     if (numIndexTuples < 1.0)
    7463        64186 :         numIndexTuples = 1.0;
    7464              : 
    7465              :     /*
    7466              :      * Estimate the number of index pages that will be retrieved.
    7467              :      *
    7468              :      * We use the simplistic method of taking a pro-rata fraction of the total
    7469              :      * number of index pages.  In effect, this counts only leaf pages and not
    7470              :      * any overhead such as index metapage or upper tree levels.
    7471              :      *
    7472              :      * In practice access to upper index levels is often nearly free because
    7473              :      * those tend to stay in cache under load; moreover, the cost involved is
    7474              :      * highly dependent on index type.  We therefore ignore such costs here
    7475              :      * and leave it to the caller to add a suitable charge if needed.
    7476              :      */
    7477       474102 :     if (index->pages > 1 && index->tuples > 1)
    7478       425466 :         numIndexPages = ceil(numIndexTuples * index->pages / index->tuples);
    7479              :     else
    7480        48636 :         numIndexPages = 1.0;
    7481              : 
    7482              :     /* fetch estimated page cost for tablespace containing index */
    7483       474102 :     get_tablespace_page_costs(index->reltablespace,
    7484              :                               &spc_random_page_cost,
    7485              :                               NULL);
    7486              : 
    7487              :     /*
    7488              :      * Now compute the disk access costs.
    7489              :      *
    7490              :      * The above calculations are all per-index-scan.  However, if we are in a
    7491              :      * nestloop inner scan, we can expect the scan to be repeated (with
    7492              :      * different search keys) for each row of the outer relation.  Likewise,
    7493              :      * ScalarArrayOpExpr quals result in multiple index scans.  This creates
    7494              :      * the potential for cache effects to reduce the number of disk page
    7495              :      * fetches needed.  We want to estimate the average per-scan I/O cost in
    7496              :      * the presence of caching.
    7497              :      *
    7498              :      * We use the Mackert-Lohman formula (see costsize.c for details) to
    7499              :      * estimate the total number of page fetches that occur.  While this
    7500              :      * wasn't what it was designed for, it seems a reasonable model anyway.
    7501              :      * Note that we are counting pages not tuples anymore, so we take N = T =
    7502              :      * index size, as if there were one "tuple" per page.
    7503              :      */
    7504       474102 :     num_outer_scans = loop_count;
    7505       474102 :     num_scans = num_sa_scans * num_outer_scans;
    7506              : 
    7507       474102 :     if (num_scans > 1)
    7508              :     {
    7509              :         double      pages_fetched;
    7510              : 
    7511              :         /* total page fetches ignoring cache effects */
    7512        57612 :         pages_fetched = numIndexPages * num_scans;
    7513              : 
    7514              :         /* use Mackert and Lohman formula to adjust for cache effects */
    7515        57612 :         pages_fetched = index_pages_fetched(pages_fetched,
    7516              :                                             index->pages,
    7517        57612 :                                             (double) index->pages,
    7518              :                                             root);
    7519              : 
    7520              :         /*
    7521              :          * Now compute the total disk access cost, and then report a pro-rated
    7522              :          * share for each outer scan.  (Don't pro-rate for ScalarArrayOpExpr,
    7523              :          * since that's internal to the indexscan.)
    7524              :          */
    7525        57612 :         indexTotalCost = (pages_fetched * spc_random_page_cost)
    7526              :             / num_outer_scans;
    7527              :     }
    7528              :     else
    7529              :     {
    7530              :         /*
    7531              :          * For a single index scan, we just charge spc_random_page_cost per
    7532              :          * page touched.
    7533              :          */
    7534       416490 :         indexTotalCost = numIndexPages * spc_random_page_cost;
    7535              :     }
    7536              : 
    7537              :     /*
    7538              :      * CPU cost: any complex expressions in the indexquals will need to be
    7539              :      * evaluated once at the start of the scan to reduce them to runtime keys
    7540              :      * to pass to the index AM (see nodeIndexscan.c).  We model the per-tuple
    7541              :      * CPU costs as cpu_index_tuple_cost plus one cpu_operator_cost per
    7542              :      * indexqual operator.  Because we have numIndexTuples as a per-scan
    7543              :      * number, we have to multiply by num_sa_scans to get the correct result
    7544              :      * for ScalarArrayOpExpr cases.  Similarly add in costs for any index
    7545              :      * ORDER BY expressions.
    7546              :      *
    7547              :      * Note: this neglects the possible costs of rechecking lossy operators.
    7548              :      * Detecting that that might be needed seems more expensive than it's
    7549              :      * worth, though, considering all the other inaccuracies here ...
    7550              :      */
    7551       474102 :     qual_arg_cost = index_other_operands_eval_cost(root, indexQuals) +
    7552       474102 :         index_other_operands_eval_cost(root, indexOrderBys);
    7553       474102 :     qual_op_cost = cpu_operator_cost *
    7554       474102 :         (list_length(indexQuals) + list_length(indexOrderBys));
    7555              : 
    7556       474102 :     indexStartupCost = qual_arg_cost;
    7557       474102 :     indexTotalCost += qual_arg_cost;
    7558       474102 :     indexTotalCost += numIndexTuples * num_sa_scans * (cpu_index_tuple_cost + qual_op_cost);
    7559              : 
    7560              :     /*
    7561              :      * Generic assumption about index correlation: there isn't any.
    7562              :      */
    7563       474102 :     indexCorrelation = 0.0;
    7564              : 
    7565              :     /*
    7566              :      * Return everything to caller.
    7567              :      */
    7568       474102 :     costs->indexStartupCost = indexStartupCost;
    7569       474102 :     costs->indexTotalCost = indexTotalCost;
    7570       474102 :     costs->indexSelectivity = indexSelectivity;
    7571       474102 :     costs->indexCorrelation = indexCorrelation;
    7572       474102 :     costs->numIndexPages = numIndexPages;
    7573       474102 :     costs->numIndexTuples = numIndexTuples;
    7574       474102 :     costs->spc_random_page_cost = spc_random_page_cost;
    7575       474102 :     costs->num_sa_scans = num_sa_scans;
    7576       474102 : }
    7577              : 
    7578              : /*
    7579              :  * If the index is partial, add its predicate to the given qual list.
    7580              :  *
    7581              :  * ANDing the index predicate with the explicitly given indexquals produces
    7582              :  * a more accurate idea of the index's selectivity.  However, we need to be
    7583              :  * careful not to insert redundant clauses, because clauselist_selectivity()
    7584              :  * is easily fooled into computing a too-low selectivity estimate.  Our
    7585              :  * approach is to add only the predicate clause(s) that cannot be proven to
    7586              :  * be implied by the given indexquals.  This successfully handles cases such
    7587              :  * as a qual "x = 42" used with a partial index "WHERE x >= 40 AND x < 50".
    7588              :  * There are many other cases where we won't detect redundancy, leading to a
    7589              :  * too-low selectivity estimate, which will bias the system in favor of using
    7590              :  * partial indexes where possible.  That is not necessarily bad though.
    7591              :  *
    7592              :  * Note that indexQuals contains RestrictInfo nodes while the indpred
    7593              :  * does not, so the output list will be mixed.  This is OK for both
    7594              :  * predicate_implied_by() and clauselist_selectivity(), but might be
    7595              :  * problematic if the result were passed to other things.
    7596              :  */
    7597              : List *
    7598       807549 : add_predicate_to_index_quals(IndexOptInfo *index, List *indexQuals)
    7599              : {
    7600       807549 :     List       *predExtraQuals = NIL;
    7601              :     ListCell   *lc;
    7602              : 
    7603       807549 :     if (index->indpred == NIL)
    7604       806540 :         return indexQuals;
    7605              : 
    7606         2024 :     foreach(lc, index->indpred)
    7607              :     {
    7608         1015 :         Node       *predQual = (Node *) lfirst(lc);
    7609         1015 :         List       *oneQual = list_make1(predQual);
    7610              : 
    7611         1015 :         if (!predicate_implied_by(oneQual, indexQuals, false))
    7612          906 :             predExtraQuals = list_concat(predExtraQuals, oneQual);
    7613              :     }
    7614         1009 :     return list_concat(predExtraQuals, indexQuals);
    7615              : }
    7616              : 
    7617              : /*
    7618              :  * Estimate correlation of btree index's first column.
    7619              :  *
    7620              :  * If we can get an estimate of the first column's ordering correlation C
    7621              :  * from pg_statistic, estimate the index correlation as C for a single-column
    7622              :  * index, or C * 0.75 for multiple columns.  The idea here is that multiple
    7623              :  * columns dilute the importance of the first column's ordering, but don't
    7624              :  * negate it entirely.
    7625              :  *
    7626              :  * We already filled in the stats tuple for *vardata when called.
    7627              :  */
    7628              : static double
    7629       317899 : btcost_correlation(IndexOptInfo *index, VariableStatData *vardata)
    7630              : {
    7631              :     Oid         sortop;
    7632              :     AttStatsSlot sslot;
    7633       317899 :     double      indexCorrelation = 0;
    7634              : 
    7635              :     Assert(HeapTupleIsValid(vardata->statsTuple));
    7636              : 
    7637       317899 :     sortop = get_opfamily_member(index->opfamily[0],
    7638       317899 :                                  index->opcintype[0],
    7639       317899 :                                  index->opcintype[0],
    7640              :                                  BTLessStrategyNumber);
    7641       635798 :     if (OidIsValid(sortop) &&
    7642       317899 :         get_attstatsslot(&sslot, vardata->statsTuple,
    7643              :                          STATISTIC_KIND_CORRELATION, sortop,
    7644              :                          ATTSTATSSLOT_NUMBERS))
    7645              :     {
    7646              :         double      varCorrelation;
    7647              : 
    7648              :         Assert(sslot.nnumbers == 1);
    7649       312862 :         varCorrelation = sslot.numbers[0];
    7650              : 
    7651       312862 :         if (index->reverse_sort[0])
    7652            0 :             varCorrelation = -varCorrelation;
    7653              : 
    7654       312862 :         if (index->nkeycolumns > 1)
    7655       108702 :             indexCorrelation = varCorrelation * 0.75;
    7656              :         else
    7657       204160 :             indexCorrelation = varCorrelation;
    7658              : 
    7659       312862 :         free_attstatsslot(&sslot);
    7660              :     }
    7661              : 
    7662       317899 :     return indexCorrelation;
    7663              : }
    7664              : 
    7665              : void
    7666       470142 : btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    7667              :                Cost *indexStartupCost, Cost *indexTotalCost,
    7668              :                Selectivity *indexSelectivity, double *indexCorrelation,
    7669              :                double *indexPages)
    7670              : {
    7671       470142 :     IndexOptInfo *index = path->indexinfo;
    7672       470142 :     GenericCosts costs = {0};
    7673       470142 :     VariableStatData vardata = {0};
    7674              :     double      numIndexTuples;
    7675              :     Cost        descentCost;
    7676              :     List       *indexBoundQuals;
    7677              :     List       *indexSkipQuals;
    7678              :     int         indexcol;
    7679              :     bool        eqQualHere;
    7680              :     bool        found_row_compare;
    7681              :     bool        found_array;
    7682              :     bool        found_is_null_op;
    7683       470142 :     bool        have_correlation = false;
    7684              :     double      num_sa_scans;
    7685       470142 :     double      correlation = 0.0;
    7686              :     ListCell   *lc;
    7687              : 
    7688              :     /*
    7689              :      * For a btree scan, only leading '=' quals plus inequality quals for the
    7690              :      * immediately next attribute contribute to index selectivity (these are
    7691              :      * the "boundary quals" that determine the starting and stopping points of
    7692              :      * the index scan).  Additional quals can suppress visits to the heap, so
    7693              :      * it's OK to count them in indexSelectivity, but they should not count
    7694              :      * for estimating numIndexTuples.  So we must examine the given indexquals
    7695              :      * to find out which ones count as boundary quals.  We rely on the
    7696              :      * knowledge that they are given in index column order.  Note that nbtree
    7697              :      * preprocessing can add skip arrays that act as leading '=' quals in the
    7698              :      * absence of ordinary input '=' quals, so in practice _most_ input quals
    7699              :      * are able to act as index bound quals (which we take into account here).
    7700              :      *
    7701              :      * For a RowCompareExpr, we consider only the first column, just as
    7702              :      * rowcomparesel() does.
    7703              :      *
    7704              :      * If there's a SAOP or skip array in the quals, we'll actually perform up
    7705              :      * to N index descents (not just one), but the underlying array key's
    7706              :      * operator can be considered to act the same as it normally does.
    7707              :      */
    7708       470142 :     indexBoundQuals = NIL;
    7709       470142 :     indexSkipQuals = NIL;
    7710       470142 :     indexcol = 0;
    7711       470142 :     eqQualHere = false;
    7712       470142 :     found_row_compare = false;
    7713       470142 :     found_array = false;
    7714       470142 :     found_is_null_op = false;
    7715       470142 :     num_sa_scans = 1;
    7716       796772 :     foreach(lc, path->indexclauses)
    7717              :     {
    7718       348798 :         IndexClause *iclause = lfirst_node(IndexClause, lc);
    7719              :         ListCell   *lc2;
    7720              : 
    7721       348798 :         if (indexcol < iclause->indexcol)
    7722              :         {
    7723        71246 :             double      num_sa_scans_prev_cols = num_sa_scans;
    7724              : 
    7725              :             /*
    7726              :              * Beginning of a new column's quals.
    7727              :              *
    7728              :              * Skip scans use skip arrays, which are ScalarArrayOp style
    7729              :              * arrays that generate their elements procedurally and on demand.
    7730              :              * Given a multi-column index on "(a, b)", and an SQL WHERE clause
    7731              :              * "WHERE b = 42", a skip scan will effectively use an indexqual
    7732              :              * "WHERE a = ANY('{every col a value}') AND b = 42".  (Obviously,
    7733              :              * the array on "a" must also return "IS NULL" matches, since our
    7734              :              * WHERE clause used no strict operator on "a").
    7735              :              *
    7736              :              * Here we consider how nbtree will backfill skip arrays for any
    7737              :              * index columns that lacked an '=' qual.  This maintains our
    7738              :              * num_sa_scans estimate, and determines if this new column (the
    7739              :              * "iclause->indexcol" column, not the prior "indexcol" column)
    7740              :              * can have its RestrictInfos/quals added to indexBoundQuals.
    7741              :              *
    7742              :              * We'll need to handle columns that have inequality quals, where
    7743              :              * the skip array generates values from a range constrained by the
    7744              :              * quals (not every possible value).  We've been maintaining
    7745              :              * indexSkipQuals to help with this; it will now contain all of
    7746              :              * the prior column's quals (that is, indexcol's quals) when they
    7747              :              * might be used for this.
    7748              :              */
    7749        71246 :             if (found_row_compare)
    7750              :             {
    7751              :                 /*
    7752              :                  * Skip arrays can't be added after a RowCompare input qual
    7753              :                  * due to limitations in nbtree
    7754              :                  */
    7755           12 :                 break;
    7756              :             }
    7757        71234 :             if (eqQualHere)
    7758              :             {
    7759              :                 /*
    7760              :                  * Don't need to add a skip array for an indexcol that already
    7761              :                  * has an '=' qual/equality constraint
    7762              :                  */
    7763        49470 :                 indexcol++;
    7764        49470 :                 indexSkipQuals = NIL;
    7765              :             }
    7766        71234 :             eqQualHere = false;
    7767              : 
    7768        72871 :             while (indexcol < iclause->indexcol)
    7769              :             {
    7770              :                 double      ndistinct;
    7771        23793 :                 bool        isdefault = true;
    7772              : 
    7773        23793 :                 found_array = true;
    7774              : 
    7775              :                 /*
    7776              :                  * A skipped attribute's ndistinct forms the basis of our
    7777              :                  * estimate of the total number of "array elements" used by
    7778              :                  * its skip array at runtime.  Look that up first.
    7779              :                  */
    7780        23793 :                 examine_indexcol_variable(root, index, indexcol, &vardata);
    7781        23793 :                 ndistinct = get_variable_numdistinct(&vardata, &isdefault);
    7782              : 
    7783        23793 :                 if (indexcol == 0)
    7784              :                 {
    7785              :                     /*
    7786              :                      * Get an estimate of the leading column's correlation in
    7787              :                      * passing (avoids rereading variable stats below)
    7788              :                      */
    7789        21758 :                     if (HeapTupleIsValid(vardata.statsTuple))
    7790        12812 :                         correlation = btcost_correlation(index, &vardata);
    7791        21758 :                     have_correlation = true;
    7792              :                 }
    7793              : 
    7794        23793 :                 ReleaseVariableStats(vardata);
    7795              : 
    7796              :                 /*
    7797              :                  * If ndistinct is a default estimate, conservatively assume
    7798              :                  * that no skipping will happen at runtime
    7799              :                  */
    7800        23793 :                 if (isdefault)
    7801              :                 {
    7802         7380 :                     num_sa_scans = num_sa_scans_prev_cols;
    7803        22156 :                     break;      /* done building indexBoundQuals */
    7804              :                 }
    7805              : 
    7806              :                 /*
    7807              :                  * Apply indexcol's indexSkipQuals selectivity to ndistinct
    7808              :                  */
    7809        16413 :                 if (indexSkipQuals != NIL)
    7810              :                 {
    7811              :                     List       *partialSkipQuals;
    7812              :                     Selectivity ndistinctfrac;
    7813              : 
    7814              :                     /*
    7815              :                      * If the index is partial, AND the index predicate with
    7816              :                      * the index-bound quals to produce a more accurate idea
    7817              :                      * of the number of distinct values for prior indexcol
    7818              :                      */
    7819          332 :                     partialSkipQuals = add_predicate_to_index_quals(index,
    7820              :                                                                     indexSkipQuals);
    7821              : 
    7822          332 :                     ndistinctfrac = clauselist_selectivity(root, partialSkipQuals,
    7823          332 :                                                            index->rel->relid,
    7824              :                                                            JOIN_INNER,
    7825              :                                                            NULL);
    7826              : 
    7827              :                     /*
    7828              :                      * If ndistinctfrac is selective (on its own), the scan is
    7829              :                      * unlikely to benefit from repositioning itself using
    7830              :                      * later quals.  Do not allow iclause->indexcol's quals to
    7831              :                      * be added to indexBoundQuals (it would increase descent
    7832              :                      * costs, without lowering numIndexTuples costs by much).
    7833              :                      */
    7834          332 :                     if (ndistinctfrac < DEFAULT_RANGE_INEQ_SEL)
    7835              :                     {
    7836          187 :                         num_sa_scans = num_sa_scans_prev_cols;
    7837          187 :                         break;  /* done building indexBoundQuals */
    7838              :                     }
    7839              : 
    7840              :                     /* Adjust ndistinct downward */
    7841          145 :                     ndistinct = rint(ndistinct * ndistinctfrac);
    7842          145 :                     ndistinct = Max(ndistinct, 1);
    7843              :                 }
    7844              : 
    7845              :                 /*
    7846              :                  * When there's no inequality quals, account for the need to
    7847              :                  * find an initial value by counting -inf/+inf as a value.
    7848              :                  *
    7849              :                  * We don't charge anything extra for possible next/prior key
    7850              :                  * index probes, which are sometimes used to find the next
    7851              :                  * valid skip array element (ahead of using the located
    7852              :                  * element value to relocate the scan to the next position
    7853              :                  * that might contain matching tuples).  It seems hard to do
    7854              :                  * better here.  Use of the skip support infrastructure often
    7855              :                  * avoids most next/prior key probes.  But even when it can't,
    7856              :                  * there's a decent chance that most individual next/prior key
    7857              :                  * probes will locate a leaf page whose key space overlaps all
    7858              :                  * of the scan's keys (even the lower-order keys) -- which
    7859              :                  * also avoids the need for a separate, extra index descent.
    7860              :                  * Note also that these probes are much cheaper than non-probe
    7861              :                  * primitive index scans: they're reliably very selective.
    7862              :                  */
    7863        16226 :                 if (indexSkipQuals == NIL)
    7864        16081 :                     ndistinct += 1;
    7865              : 
    7866              :                 /*
    7867              :                  * Update num_sa_scans estimate by multiplying by ndistinct.
    7868              :                  *
    7869              :                  * We make the pessimistic assumption that there is no
    7870              :                  * naturally occurring cross-column correlation.  This is
    7871              :                  * often wrong, but it seems best to err on the side of not
    7872              :                  * expecting skipping to be helpful...
    7873              :                  */
    7874        16226 :                 num_sa_scans *= ndistinct;
    7875              : 
    7876              :                 /*
    7877              :                  * ...but back out of adding this latest group of 1 or more
    7878              :                  * skip arrays when num_sa_scans exceeds the total number of
    7879              :                  * index pages (revert to num_sa_scans from before indexcol).
    7880              :                  * This causes a sharp discontinuity in cost (as a function of
    7881              :                  * the indexcol's ndistinct), but that is representative of
    7882              :                  * actual runtime costs.
    7883              :                  *
    7884              :                  * Note that skipping is helpful when each primitive index
    7885              :                  * scan only manages to skip over 1 or 2 irrelevant leaf pages
    7886              :                  * on average.  Skip arrays bring savings in CPU costs due to
    7887              :                  * the scan not needing to evaluate indexquals against every
    7888              :                  * tuple, which can greatly exceed any savings in I/O costs.
    7889              :                  * This test is a test of whether num_sa_scans implies that
    7890              :                  * we're past the point where the ability to skip ceases to
    7891              :                  * lower the scan's costs (even qual evaluation CPU costs).
    7892              :                  */
    7893        16226 :                 if (index->pages < num_sa_scans)
    7894              :                 {
    7895        14589 :                     num_sa_scans = num_sa_scans_prev_cols;
    7896        14589 :                     break;      /* done building indexBoundQuals */
    7897              :                 }
    7898              : 
    7899         1637 :                 indexcol++;
    7900         1637 :                 indexSkipQuals = NIL;
    7901              :             }
    7902              : 
    7903              :             /*
    7904              :              * Finished considering the need to add skip arrays to bridge an
    7905              :              * initial eqQualHere gap between the old and new index columns
    7906              :              * (or there was no initial eqQualHere gap in the first place).
    7907              :              *
    7908              :              * If an initial gap could not be bridged, then new column's quals
    7909              :              * (i.e. iclause->indexcol's quals) won't go into indexBoundQuals,
    7910              :              * and so won't affect our final numIndexTuples estimate.
    7911              :              */
    7912        71234 :             if (indexcol != iclause->indexcol)
    7913        22156 :                 break;          /* done building indexBoundQuals */
    7914              :         }
    7915              : 
    7916              :         Assert(indexcol == iclause->indexcol);
    7917              : 
    7918              :         /* Examine each indexqual associated with this index clause */
    7919       654635 :         foreach(lc2, iclause->indexquals)
    7920              :         {
    7921       328005 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
    7922       328005 :             Expr       *clause = rinfo->clause;
    7923       328005 :             Oid         clause_op = InvalidOid;
    7924              :             int         op_strategy;
    7925              : 
    7926       328005 :             if (IsA(clause, OpExpr))
    7927              :             {
    7928       318530 :                 OpExpr     *op = (OpExpr *) clause;
    7929              : 
    7930       318530 :                 clause_op = op->opno;
    7931              :             }
    7932         9475 :             else if (IsA(clause, RowCompareExpr))
    7933              :             {
    7934          198 :                 RowCompareExpr *rc = (RowCompareExpr *) clause;
    7935              : 
    7936          198 :                 clause_op = linitial_oid(rc->opnos);
    7937          198 :                 found_row_compare = true;
    7938              :             }
    7939         9277 :             else if (IsA(clause, ScalarArrayOpExpr))
    7940              :             {
    7941         8135 :                 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
    7942         8135 :                 Node       *other_operand = (Node *) lsecond(saop->args);
    7943         8135 :                 double      alength = estimate_array_length(root, other_operand);
    7944              : 
    7945         8135 :                 clause_op = saop->opno;
    7946         8135 :                 found_array = true;
    7947              :                 /* estimate SA descents by indexBoundQuals only */
    7948         8135 :                 if (alength > 1)
    7949         7981 :                     num_sa_scans *= alength;
    7950              :             }
    7951         1142 :             else if (IsA(clause, NullTest))
    7952              :             {
    7953         1142 :                 NullTest   *nt = (NullTest *) clause;
    7954              : 
    7955         1142 :                 if (nt->nulltesttype == IS_NULL)
    7956              :                 {
    7957          120 :                     found_is_null_op = true;
    7958              :                     /* IS NULL is like = for selectivity/skip scan purposes */
    7959          120 :                     eqQualHere = true;
    7960              :                 }
    7961              :             }
    7962              :             else
    7963            0 :                 elog(ERROR, "unsupported indexqual type: %d",
    7964              :                      (int) nodeTag(clause));
    7965              : 
    7966              :             /* check for equality operator */
    7967       328005 :             if (OidIsValid(clause_op))
    7968              :             {
    7969       326863 :                 op_strategy = get_op_opfamily_strategy(clause_op,
    7970       326863 :                                                        index->opfamily[indexcol]);
    7971              :                 Assert(op_strategy != 0);   /* not a member of opfamily?? */
    7972       326863 :                 if (op_strategy == BTEqualStrategyNumber)
    7973       310290 :                     eqQualHere = true;
    7974              :             }
    7975              : 
    7976       328005 :             indexBoundQuals = lappend(indexBoundQuals, rinfo);
    7977              : 
    7978              :             /*
    7979              :              * We apply inequality selectivities to estimate index descent
    7980              :              * costs with scans that use skip arrays.  Save this indexcol's
    7981              :              * RestrictInfos if it looks like they'll be needed for that.
    7982              :              */
    7983       328005 :             if (!eqQualHere && !found_row_compare &&
    7984        17046 :                 indexcol < index->nkeycolumns - 1)
    7985         2856 :                 indexSkipQuals = lappend(indexSkipQuals, rinfo);
    7986              :         }
    7987              :     }
    7988              : 
    7989              :     /*
    7990              :      * If index is unique and we found an '=' clause for each column, we can
    7991              :      * just assume numIndexTuples = 1 and skip the expensive
    7992              :      * clauselist_selectivity calculations.  However, an array or NullTest
    7993              :      * always invalidates that theory (even when eqQualHere has been set).
    7994              :      */
    7995       470142 :     if (index->unique &&
    7996       381469 :         indexcol == index->nkeycolumns - 1 &&
    7997       142022 :         eqQualHere &&
    7998       142022 :         !found_array &&
    7999       138183 :         !found_is_null_op)
    8000       138159 :         numIndexTuples = 1.0;
    8001              :     else
    8002              :     {
    8003              :         List       *selectivityQuals;
    8004              :         Selectivity btreeSelectivity;
    8005              : 
    8006              :         /*
    8007              :          * If the index is partial, AND the index predicate with the
    8008              :          * index-bound quals to produce a more accurate idea of the number of
    8009              :          * rows covered by the bound conditions.
    8010              :          */
    8011       331983 :         selectivityQuals = add_predicate_to_index_quals(index, indexBoundQuals);
    8012              : 
    8013       331983 :         btreeSelectivity = clauselist_selectivity(root, selectivityQuals,
    8014       331983 :                                                   index->rel->relid,
    8015              :                                                   JOIN_INNER,
    8016              :                                                   NULL);
    8017       331983 :         numIndexTuples = btreeSelectivity * index->rel->tuples;
    8018              : 
    8019              :         /*
    8020              :          * btree automatically combines individual array element primitive
    8021              :          * index scans whenever the tuples covered by the next set of array
    8022              :          * keys are close to tuples covered by the current set.  That puts a
    8023              :          * natural ceiling on the worst case number of descents -- there
    8024              :          * cannot possibly be more than one descent per leaf page scanned.
    8025              :          *
    8026              :          * Clamp the number of descents to at most 1/3 the number of index
    8027              :          * pages.  This avoids implausibly high estimates with low selectivity
    8028              :          * paths, where scans usually require only one or two descents.  This
    8029              :          * is most likely to help when there are several SAOP clauses, where
    8030              :          * naively accepting the total number of distinct combinations of
    8031              :          * array elements as the number of descents would frequently lead to
    8032              :          * wild overestimates.
    8033              :          *
    8034              :          * We somewhat arbitrarily don't just make the cutoff the total number
    8035              :          * of leaf pages (we make it 1/3 the total number of pages instead) to
    8036              :          * give the btree code credit for its ability to continue on the leaf
    8037              :          * level with low selectivity scans.
    8038              :          *
    8039              :          * Note: num_sa_scans includes both ScalarArrayOp array elements and
    8040              :          * skip array elements whose qual affects our numIndexTuples estimate.
    8041              :          */
    8042       331983 :         num_sa_scans = Min(num_sa_scans, ceil(index->pages * 0.3333333));
    8043       331983 :         num_sa_scans = Max(num_sa_scans, 1);
    8044              : 
    8045              :         /*
    8046              :          * As in genericcostestimate(), we have to adjust for any array quals
    8047              :          * included in indexBoundQuals, and then round to integer.
    8048              :          *
    8049              :          * It is tempting to make genericcostestimate behave as if array
    8050              :          * clauses work in almost the same way as scalar operators during
    8051              :          * btree scans, making the top-level scan look like a continuous scan
    8052              :          * (as opposed to num_sa_scans-many primitive index scans).  After
    8053              :          * all, btree scans mostly work like that at runtime.  However, such a
    8054              :          * scheme would badly bias genericcostestimate's simplistic approach
    8055              :          * to calculating numIndexPages through prorating.
    8056              :          *
    8057              :          * Stick with the approach taken by non-native SAOP scans for now.
    8058              :          * genericcostestimate will use the Mackert-Lohman formula to
    8059              :          * compensate for repeat page fetches, even though that definitely
    8060              :          * won't happen during btree scans (not for leaf pages, at least).
    8061              :          * We're usually very pessimistic about the number of primitive index
    8062              :          * scans that will be required, but it's not clear how to do better.
    8063              :          */
    8064       331983 :         numIndexTuples = rint(numIndexTuples / num_sa_scans);
    8065              :     }
    8066              : 
    8067              :     /*
    8068              :      * Now do generic index cost estimation.
    8069              :      */
    8070       470142 :     costs.numIndexTuples = numIndexTuples;
    8071       470142 :     costs.num_sa_scans = num_sa_scans;
    8072              : 
    8073       470142 :     genericcostestimate(root, path, loop_count, &costs);
    8074              : 
    8075              :     /*
    8076              :      * Add a CPU-cost component to represent the costs of initial btree
    8077              :      * descent.  We don't charge any I/O cost for touching upper btree levels,
    8078              :      * since they tend to stay in cache, but we still have to do about log2(N)
    8079              :      * comparisons to descend a btree of N leaf tuples.  We charge one
    8080              :      * cpu_operator_cost per comparison.
    8081              :      *
    8082              :      * If there are SAOP or skip array keys, charge this once per estimated
    8083              :      * index descent.  The ones after the first one are not startup cost so
    8084              :      * far as the overall plan goes, so just add them to "total" cost.
    8085              :      */
    8086       470142 :     if (index->tuples > 1)        /* avoid computing log(0) */
    8087              :     {
    8088       425968 :         descentCost = ceil(log(index->tuples) / log(2.0)) * cpu_operator_cost;
    8089       425968 :         costs.indexStartupCost += descentCost;
    8090       425968 :         costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8091              :     }
    8092              : 
    8093              :     /*
    8094              :      * Even though we're not charging I/O cost for touching upper btree pages,
    8095              :      * it's still reasonable to charge some CPU cost per page descended
    8096              :      * through.  Moreover, if we had no such charge at all, bloated indexes
    8097              :      * would appear to have the same search cost as unbloated ones, at least
    8098              :      * in cases where only a single leaf page is expected to be visited.  This
    8099              :      * cost is somewhat arbitrarily set at 50x cpu_operator_cost per page
    8100              :      * touched.  The number of such pages is btree tree height plus one (ie,
    8101              :      * we charge for the leaf page too).  As above, charge once per estimated
    8102              :      * SAOP/skip array descent.
    8103              :      */
    8104       470142 :     descentCost = (index->tree_height + 1) * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8105       470142 :     costs.indexStartupCost += descentCost;
    8106       470142 :     costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8107              : 
    8108       470142 :     if (!have_correlation)
    8109              :     {
    8110       448384 :         examine_indexcol_variable(root, index, 0, &vardata);
    8111       448384 :         if (HeapTupleIsValid(vardata.statsTuple))
    8112       305087 :             costs.indexCorrelation = btcost_correlation(index, &vardata);
    8113       448384 :         ReleaseVariableStats(vardata);
    8114              :     }
    8115              :     else
    8116              :     {
    8117              :         /* btcost_correlation already called earlier on */
    8118        21758 :         costs.indexCorrelation = correlation;
    8119              :     }
    8120              : 
    8121       470142 :     *indexStartupCost = costs.indexStartupCost;
    8122       470142 :     *indexTotalCost = costs.indexTotalCost;
    8123       470142 :     *indexSelectivity = costs.indexSelectivity;
    8124       470142 :     *indexCorrelation = costs.indexCorrelation;
    8125       470142 :     *indexPages = costs.numIndexPages;
    8126       470142 : }
    8127              : 
    8128              : void
    8129          215 : hashcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    8130              :                  Cost *indexStartupCost, Cost *indexTotalCost,
    8131              :                  Selectivity *indexSelectivity, double *indexCorrelation,
    8132              :                  double *indexPages)
    8133              : {
    8134          215 :     GenericCosts costs = {0};
    8135              : 
    8136          215 :     genericcostestimate(root, path, loop_count, &costs);
    8137              : 
    8138              :     /*
    8139              :      * A hash index has no descent costs as such, since the index AM can go
    8140              :      * directly to the target bucket after computing the hash value.  There
    8141              :      * are a couple of other hash-specific costs that we could conceivably add
    8142              :      * here, though:
    8143              :      *
    8144              :      * Ideally we'd charge spc_random_page_cost for each page in the target
    8145              :      * bucket, not just the numIndexPages pages that genericcostestimate
    8146              :      * thought we'd visit.  However in most cases we don't know which bucket
    8147              :      * that will be.  There's no point in considering the average bucket size
    8148              :      * because the hash AM makes sure that's always one page.
    8149              :      *
    8150              :      * Likewise, we could consider charging some CPU for each index tuple in
    8151              :      * the bucket, if we knew how many there were.  But the per-tuple cost is
    8152              :      * just a hash value comparison, not a general datatype-dependent
    8153              :      * comparison, so any such charge ought to be quite a bit less than
    8154              :      * cpu_operator_cost; which makes it probably not worth worrying about.
    8155              :      *
    8156              :      * A bigger issue is that chance hash-value collisions will result in
    8157              :      * wasted probes into the heap.  We don't currently attempt to model this
    8158              :      * cost on the grounds that it's rare, but maybe it's not rare enough.
    8159              :      * (Any fix for this ought to consider the generic lossy-operator problem,
    8160              :      * though; it's not entirely hash-specific.)
    8161              :      */
    8162              : 
    8163          215 :     *indexStartupCost = costs.indexStartupCost;
    8164          215 :     *indexTotalCost = costs.indexTotalCost;
    8165          215 :     *indexSelectivity = costs.indexSelectivity;
    8166          215 :     *indexCorrelation = costs.indexCorrelation;
    8167          215 :     *indexPages = costs.numIndexPages;
    8168          215 : }
    8169              : 
    8170              : void
    8171         2447 : gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    8172              :                  Cost *indexStartupCost, Cost *indexTotalCost,
    8173              :                  Selectivity *indexSelectivity, double *indexCorrelation,
    8174              :                  double *indexPages)
    8175              : {
    8176         2447 :     IndexOptInfo *index = path->indexinfo;
    8177         2447 :     GenericCosts costs = {0};
    8178              :     Cost        descentCost;
    8179              : 
    8180         2447 :     genericcostestimate(root, path, loop_count, &costs);
    8181              : 
    8182              :     /*
    8183              :      * We model index descent costs similarly to those for btree, but to do
    8184              :      * that we first need an idea of the tree height.  We somewhat arbitrarily
    8185              :      * assume that the fanout is 100, meaning the tree height is at most
    8186              :      * log100(index->pages).
    8187              :      *
    8188              :      * Although this computation isn't really expensive enough to require
    8189              :      * caching, we might as well use index->tree_height to cache it.
    8190              :      */
    8191         2447 :     if (index->tree_height < 0) /* unknown? */
    8192              :     {
    8193         2440 :         if (index->pages > 1) /* avoid computing log(0) */
    8194         1360 :             index->tree_height = (int) (log(index->pages) / log(100.0));
    8195              :         else
    8196         1080 :             index->tree_height = 0;
    8197              :     }
    8198              : 
    8199              :     /*
    8200              :      * Add a CPU-cost component to represent the costs of initial descent. We
    8201              :      * just use log(N) here not log2(N) since the branching factor isn't
    8202              :      * necessarily two anyway.  As for btree, charge once per SA scan.
    8203              :      */
    8204         2447 :     if (index->tuples > 1)        /* avoid computing log(0) */
    8205              :     {
    8206         2447 :         descentCost = ceil(log(index->tuples)) * cpu_operator_cost;
    8207         2447 :         costs.indexStartupCost += descentCost;
    8208         2447 :         costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8209              :     }
    8210              : 
    8211              :     /*
    8212              :      * Likewise add a per-page charge, calculated the same as for btrees.
    8213              :      */
    8214         2447 :     descentCost = (index->tree_height + 1) * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8215         2447 :     costs.indexStartupCost += descentCost;
    8216         2447 :     costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8217              : 
    8218         2447 :     *indexStartupCost = costs.indexStartupCost;
    8219         2447 :     *indexTotalCost = costs.indexTotalCost;
    8220         2447 :     *indexSelectivity = costs.indexSelectivity;
    8221         2447 :     *indexCorrelation = costs.indexCorrelation;
    8222         2447 :     *indexPages = costs.numIndexPages;
    8223         2447 : }
    8224              : 
    8225              : void
    8226          892 : spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    8227              :                 Cost *indexStartupCost, Cost *indexTotalCost,
    8228              :                 Selectivity *indexSelectivity, double *indexCorrelation,
    8229              :                 double *indexPages)
    8230              : {
    8231          892 :     IndexOptInfo *index = path->indexinfo;
    8232          892 :     GenericCosts costs = {0};
    8233              :     Cost        descentCost;
    8234              : 
    8235          892 :     genericcostestimate(root, path, loop_count, &costs);
    8236              : 
    8237              :     /*
    8238              :      * We model index descent costs similarly to those for btree, but to do
    8239              :      * that we first need an idea of the tree height.  We somewhat arbitrarily
    8240              :      * assume that the fanout is 100, meaning the tree height is at most
    8241              :      * log100(index->pages).
    8242              :      *
    8243              :      * Although this computation isn't really expensive enough to require
    8244              :      * caching, we might as well use index->tree_height to cache it.
    8245              :      */
    8246          892 :     if (index->tree_height < 0) /* unknown? */
    8247              :     {
    8248          889 :         if (index->pages > 1) /* avoid computing log(0) */
    8249          889 :             index->tree_height = (int) (log(index->pages) / log(100.0));
    8250              :         else
    8251            0 :             index->tree_height = 0;
    8252              :     }
    8253              : 
    8254              :     /*
    8255              :      * Add a CPU-cost component to represent the costs of initial descent. We
    8256              :      * just use log(N) here not log2(N) since the branching factor isn't
    8257              :      * necessarily two anyway.  As for btree, charge once per SA scan.
    8258              :      */
    8259          892 :     if (index->tuples > 1)        /* avoid computing log(0) */
    8260              :     {
    8261          892 :         descentCost = ceil(log(index->tuples)) * cpu_operator_cost;
    8262          892 :         costs.indexStartupCost += descentCost;
    8263          892 :         costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8264              :     }
    8265              : 
    8266              :     /*
    8267              :      * Likewise add a per-page charge, calculated the same as for btrees.
    8268              :      */
    8269          892 :     descentCost = (index->tree_height + 1) * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8270          892 :     costs.indexStartupCost += descentCost;
    8271          892 :     costs.indexTotalCost += costs.num_sa_scans * descentCost;
    8272              : 
    8273          892 :     *indexStartupCost = costs.indexStartupCost;
    8274          892 :     *indexTotalCost = costs.indexTotalCost;
    8275          892 :     *indexSelectivity = costs.indexSelectivity;
    8276          892 :     *indexCorrelation = costs.indexCorrelation;
    8277          892 :     *indexPages = costs.numIndexPages;
    8278          892 : }
    8279              : 
    8280              : 
    8281              : /*
    8282              :  * Support routines for gincostestimate
    8283              :  */
    8284              : 
    8285              : typedef struct
    8286              : {
    8287              :     bool        attHasFullScan[INDEX_MAX_KEYS];
    8288              :     bool        attHasNormalScan[INDEX_MAX_KEYS];
    8289              :     double      partialEntries;
    8290              :     double      exactEntries;
    8291              :     double      searchEntries;
    8292              :     double      arrayScans;
    8293              : } GinQualCounts;
    8294              : 
    8295              : /*
    8296              :  * Estimate the number of index terms that need to be searched for while
    8297              :  * testing the given GIN query, and increment the counts in *counts
    8298              :  * appropriately.  If the query is unsatisfiable, return false.
    8299              :  */
    8300              : static bool
    8301         1240 : gincost_pattern(IndexOptInfo *index, int indexcol,
    8302              :                 Oid clause_op, Datum query,
    8303              :                 GinQualCounts *counts)
    8304              : {
    8305              :     FmgrInfo    flinfo;
    8306              :     Oid         extractProcOid;
    8307              :     Oid         collation;
    8308              :     int         strategy_op;
    8309              :     Oid         lefttype,
    8310              :                 righttype;
    8311         1240 :     int32       nentries = 0;
    8312         1240 :     bool       *partial_matches = NULL;
    8313         1240 :     Pointer    *extra_data = NULL;
    8314         1240 :     bool       *nullFlags = NULL;
    8315         1240 :     int32       searchMode = GIN_SEARCH_MODE_DEFAULT;
    8316              :     int32       i;
    8317              : 
    8318              :     Assert(indexcol < index->nkeycolumns);
    8319              : 
    8320              :     /*
    8321              :      * Get the operator's strategy number and declared input data types within
    8322              :      * the index opfamily.  (We don't need the latter, but we use
    8323              :      * get_op_opfamily_properties because it will throw error if it fails to
    8324              :      * find a matching pg_amop entry.)
    8325              :      */
    8326         1240 :     get_op_opfamily_properties(clause_op, index->opfamily[indexcol], false,
    8327              :                                &strategy_op, &lefttype, &righttype);
    8328              : 
    8329              :     /*
    8330              :      * GIN always uses the "default" support functions, which are those with
    8331              :      * lefttype == righttype == the opclass' opcintype (see
    8332              :      * IndexSupportInitialize in relcache.c).
    8333              :      */
    8334         1240 :     extractProcOid = get_opfamily_proc(index->opfamily[indexcol],
    8335         1240 :                                        index->opcintype[indexcol],
    8336         1240 :                                        index->opcintype[indexcol],
    8337              :                                        GIN_EXTRACTQUERY_PROC);
    8338              : 
    8339         1240 :     if (!OidIsValid(extractProcOid))
    8340              :     {
    8341              :         /* should not happen; throw same error as index_getprocinfo */
    8342            0 :         elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
    8343              :              GIN_EXTRACTQUERY_PROC, indexcol + 1,
    8344              :              get_rel_name(index->indexoid));
    8345              :     }
    8346              : 
    8347              :     /*
    8348              :      * Choose collation to pass to extractProc (should match initGinState).
    8349              :      */
    8350         1240 :     if (OidIsValid(index->indexcollations[indexcol]))
    8351          207 :         collation = index->indexcollations[indexcol];
    8352              :     else
    8353         1033 :         collation = DEFAULT_COLLATION_OID;
    8354              : 
    8355         1240 :     fmgr_info(extractProcOid, &flinfo);
    8356              : 
    8357         1240 :     set_fn_opclass_options(&flinfo, index->opclassoptions[indexcol]);
    8358              : 
    8359         1240 :     FunctionCall7Coll(&flinfo,
    8360              :                       collation,
    8361              :                       query,
    8362              :                       PointerGetDatum(&nentries),
    8363              :                       UInt16GetDatum(strategy_op),
    8364              :                       PointerGetDatum(&partial_matches),
    8365              :                       PointerGetDatum(&extra_data),
    8366              :                       PointerGetDatum(&nullFlags),
    8367              :                       PointerGetDatum(&searchMode));
    8368              : 
    8369         1240 :     if (nentries <= 0 && searchMode == GIN_SEARCH_MODE_DEFAULT)
    8370              :     {
    8371              :         /* No match is possible */
    8372            6 :         return false;
    8373              :     }
    8374              : 
    8375         4838 :     for (i = 0; i < nentries; i++)
    8376              :     {
    8377              :         /*
    8378              :          * For partial match we haven't any information to estimate number of
    8379              :          * matched entries in index, so, we just estimate it as 100
    8380              :          */
    8381         3604 :         if (partial_matches && partial_matches[i])
    8382          347 :             counts->partialEntries += 100;
    8383              :         else
    8384         3257 :             counts->exactEntries++;
    8385              : 
    8386         3604 :         counts->searchEntries++;
    8387              :     }
    8388              : 
    8389         1234 :     if (searchMode == GIN_SEARCH_MODE_DEFAULT)
    8390              :     {
    8391          992 :         counts->attHasNormalScan[indexcol] = true;
    8392              :     }
    8393          242 :     else if (searchMode == GIN_SEARCH_MODE_INCLUDE_EMPTY)
    8394              :     {
    8395              :         /* Treat "include empty" like an exact-match item */
    8396           22 :         counts->attHasNormalScan[indexcol] = true;
    8397           22 :         counts->exactEntries++;
    8398           22 :         counts->searchEntries++;
    8399              :     }
    8400              :     else
    8401              :     {
    8402              :         /* It's GIN_SEARCH_MODE_ALL */
    8403          220 :         counts->attHasFullScan[indexcol] = true;
    8404              :     }
    8405              : 
    8406         1234 :     return true;
    8407              : }
    8408              : 
    8409              : /*
    8410              :  * Estimate the number of index terms that need to be searched for while
    8411              :  * testing the given GIN index clause, and increment the counts in *counts
    8412              :  * appropriately.  If the query is unsatisfiable, return false.
    8413              :  */
    8414              : static bool
    8415         1234 : gincost_opexpr(PlannerInfo *root,
    8416              :                IndexOptInfo *index,
    8417              :                int indexcol,
    8418              :                OpExpr *clause,
    8419              :                GinQualCounts *counts)
    8420              : {
    8421         1234 :     Oid         clause_op = clause->opno;
    8422         1234 :     Node       *operand = (Node *) lsecond(clause->args);
    8423              : 
    8424              :     /* aggressively reduce to a constant, and look through relabeling */
    8425         1234 :     operand = estimate_expression_value(root, operand);
    8426              : 
    8427         1234 :     if (IsA(operand, RelabelType))
    8428            0 :         operand = (Node *) ((RelabelType *) operand)->arg;
    8429              : 
    8430              :     /*
    8431              :      * It's impossible to call extractQuery method for unknown operand. So
    8432              :      * unless operand is a Const we can't do much; just assume there will be
    8433              :      * one ordinary search entry from the operand at runtime.
    8434              :      */
    8435         1234 :     if (!IsA(operand, Const))
    8436              :     {
    8437            0 :         counts->exactEntries++;
    8438            0 :         counts->searchEntries++;
    8439            0 :         return true;
    8440              :     }
    8441              : 
    8442              :     /* If Const is null, there can be no matches */
    8443         1234 :     if (((Const *) operand)->constisnull)
    8444            0 :         return false;
    8445              : 
    8446              :     /* Otherwise, apply extractQuery and get the actual term counts */
    8447         1234 :     return gincost_pattern(index, indexcol, clause_op,
    8448              :                            ((Const *) operand)->constvalue,
    8449              :                            counts);
    8450              : }
    8451              : 
    8452              : /*
    8453              :  * Estimate the number of index terms that need to be searched for while
    8454              :  * testing the given GIN index clause, and increment the counts in *counts
    8455              :  * appropriately.  If the query is unsatisfiable, return false.
    8456              :  *
    8457              :  * A ScalarArrayOpExpr will give rise to N separate indexscans at runtime,
    8458              :  * each of which involves one value from the RHS array, plus all the
    8459              :  * non-array quals (if any).  To model this, we average the counts across
    8460              :  * the RHS elements, and add the averages to the counts in *counts (which
    8461              :  * correspond to per-indexscan costs).  We also multiply counts->arrayScans
    8462              :  * by N, causing gincostestimate to scale up its estimates accordingly.
    8463              :  */
    8464              : static bool
    8465            3 : gincost_scalararrayopexpr(PlannerInfo *root,
    8466              :                           IndexOptInfo *index,
    8467              :                           int indexcol,
    8468              :                           ScalarArrayOpExpr *clause,
    8469              :                           double numIndexEntries,
    8470              :                           GinQualCounts *counts)
    8471              : {
    8472            3 :     Oid         clause_op = clause->opno;
    8473            3 :     Node       *rightop = (Node *) lsecond(clause->args);
    8474              :     ArrayType  *arrayval;
    8475              :     int16       elmlen;
    8476              :     bool        elmbyval;
    8477              :     char        elmalign;
    8478              :     int         numElems;
    8479              :     Datum      *elemValues;
    8480              :     bool       *elemNulls;
    8481              :     GinQualCounts arraycounts;
    8482            3 :     int         numPossible = 0;
    8483              :     int         i;
    8484              : 
    8485              :     Assert(clause->useOr);
    8486              : 
    8487              :     /* aggressively reduce to a constant, and look through relabeling */
    8488            3 :     rightop = estimate_expression_value(root, rightop);
    8489              : 
    8490            3 :     if (IsA(rightop, RelabelType))
    8491            0 :         rightop = (Node *) ((RelabelType *) rightop)->arg;
    8492              : 
    8493              :     /*
    8494              :      * It's impossible to call extractQuery method for unknown operand. So
    8495              :      * unless operand is a Const we can't do much; just assume there will be
    8496              :      * one ordinary search entry from each array entry at runtime, and fall
    8497              :      * back on a probably-bad estimate of the number of array entries.
    8498              :      */
    8499            3 :     if (!IsA(rightop, Const))
    8500              :     {
    8501            0 :         counts->exactEntries++;
    8502            0 :         counts->searchEntries++;
    8503            0 :         counts->arrayScans *= estimate_array_length(root, rightop);
    8504            0 :         return true;
    8505              :     }
    8506              : 
    8507              :     /* If Const is null, there can be no matches */
    8508            3 :     if (((Const *) rightop)->constisnull)
    8509            0 :         return false;
    8510              : 
    8511              :     /* Otherwise, extract the array elements and iterate over them */
    8512            3 :     arrayval = DatumGetArrayTypeP(((Const *) rightop)->constvalue);
    8513            3 :     get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
    8514              :                          &elmlen, &elmbyval, &elmalign);
    8515            3 :     deconstruct_array(arrayval,
    8516              :                       ARR_ELEMTYPE(arrayval),
    8517              :                       elmlen, elmbyval, elmalign,
    8518              :                       &elemValues, &elemNulls, &numElems);
    8519              : 
    8520            3 :     memset(&arraycounts, 0, sizeof(arraycounts));
    8521              : 
    8522            9 :     for (i = 0; i < numElems; i++)
    8523              :     {
    8524              :         GinQualCounts elemcounts;
    8525              : 
    8526              :         /* NULL can't match anything, so ignore, as the executor will */
    8527            6 :         if (elemNulls[i])
    8528            0 :             continue;
    8529              : 
    8530              :         /* Otherwise, apply extractQuery and get the actual term counts */
    8531            6 :         memset(&elemcounts, 0, sizeof(elemcounts));
    8532              : 
    8533            6 :         if (gincost_pattern(index, indexcol, clause_op, elemValues[i],
    8534              :                             &elemcounts))
    8535              :         {
    8536              :             /* We ignore array elements that are unsatisfiable patterns */
    8537            6 :             numPossible++;
    8538              : 
    8539            6 :             if (elemcounts.attHasFullScan[indexcol] &&
    8540            0 :                 !elemcounts.attHasNormalScan[indexcol])
    8541              :             {
    8542              :                 /*
    8543              :                  * Full index scan will be required.  We treat this as if
    8544              :                  * every key in the index had been listed in the query; is
    8545              :                  * that reasonable?
    8546              :                  */
    8547            0 :                 elemcounts.partialEntries = 0;
    8548            0 :                 elemcounts.exactEntries = numIndexEntries;
    8549            0 :                 elemcounts.searchEntries = numIndexEntries;
    8550              :             }
    8551            6 :             arraycounts.partialEntries += elemcounts.partialEntries;
    8552            6 :             arraycounts.exactEntries += elemcounts.exactEntries;
    8553            6 :             arraycounts.searchEntries += elemcounts.searchEntries;
    8554              :         }
    8555              :     }
    8556              : 
    8557            3 :     if (numPossible == 0)
    8558              :     {
    8559              :         /* No satisfiable patterns in the array */
    8560            0 :         return false;
    8561              :     }
    8562              : 
    8563              :     /*
    8564              :      * Now add the averages to the global counts.  This will give us an
    8565              :      * estimate of the average number of terms searched for in each indexscan,
    8566              :      * including contributions from both array and non-array quals.
    8567              :      */
    8568            3 :     counts->partialEntries += arraycounts.partialEntries / numPossible;
    8569            3 :     counts->exactEntries += arraycounts.exactEntries / numPossible;
    8570            3 :     counts->searchEntries += arraycounts.searchEntries / numPossible;
    8571              : 
    8572            3 :     counts->arrayScans *= numPossible;
    8573              : 
    8574            3 :     return true;
    8575              : }
    8576              : 
    8577              : /*
    8578              :  * GIN has search behavior completely different from other index types
    8579              :  */
    8580              : void
    8581         1132 : gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    8582              :                 Cost *indexStartupCost, Cost *indexTotalCost,
    8583              :                 Selectivity *indexSelectivity, double *indexCorrelation,
    8584              :                 double *indexPages)
    8585              : {
    8586         1132 :     IndexOptInfo *index = path->indexinfo;
    8587         1132 :     List       *indexQuals = get_quals_from_indexclauses(path->indexclauses);
    8588              :     List       *selectivityQuals;
    8589         1132 :     double      numPages = index->pages,
    8590         1132 :                 numTuples = index->tuples;
    8591              :     double      numEntryPages,
    8592              :                 numDataPages,
    8593              :                 numPendingPages,
    8594              :                 numEntries;
    8595              :     GinQualCounts counts;
    8596              :     bool        matchPossible;
    8597              :     bool        fullIndexScan;
    8598              :     double      partialScale;
    8599              :     double      entryPagesFetched,
    8600              :                 dataPagesFetched,
    8601              :                 dataPagesFetchedBySel;
    8602              :     double      qual_op_cost,
    8603              :                 qual_arg_cost,
    8604              :                 spc_random_page_cost,
    8605              :                 outer_scans;
    8606              :     Cost        descentCost;
    8607              :     Relation    indexRel;
    8608              :     GinStatsData ginStats;
    8609              :     ListCell   *lc;
    8610              :     int         i;
    8611              : 
    8612              :     /*
    8613              :      * Obtain statistical information from the meta page, if possible.  Else
    8614              :      * set ginStats to zeroes, and we'll cope below.
    8615              :      */
    8616         1132 :     if (!index->hypothetical)
    8617              :     {
    8618              :         /* Lock should have already been obtained in plancat.c */
    8619         1132 :         indexRel = index_open(index->indexoid, NoLock);
    8620         1132 :         ginGetStats(indexRel, &ginStats);
    8621         1132 :         index_close(indexRel, NoLock);
    8622              :     }
    8623              :     else
    8624              :     {
    8625            0 :         memset(&ginStats, 0, sizeof(ginStats));
    8626              :     }
    8627              : 
    8628              :     /*
    8629              :      * Assuming we got valid (nonzero) stats at all, nPendingPages can be
    8630              :      * trusted, but the other fields are data as of the last VACUUM.  We can
    8631              :      * scale them up to account for growth since then, but that method only
    8632              :      * goes so far; in the worst case, the stats might be for a completely
    8633              :      * empty index, and scaling them will produce pretty bogus numbers.
    8634              :      * Somewhat arbitrarily, set the cutoff for doing scaling at 4X growth; if
    8635              :      * it's grown more than that, fall back to estimating things only from the
    8636              :      * assumed-accurate index size.  But we'll trust nPendingPages in any case
    8637              :      * so long as it's not clearly insane, ie, more than the index size.
    8638              :      */
    8639         1132 :     if (ginStats.nPendingPages < numPages)
    8640         1132 :         numPendingPages = ginStats.nPendingPages;
    8641              :     else
    8642            0 :         numPendingPages = 0;
    8643              : 
    8644         1132 :     if (numPages > 0 && ginStats.nTotalPages <= numPages &&
    8645         1132 :         ginStats.nTotalPages > numPages / 4 &&
    8646         1106 :         ginStats.nEntryPages > 0 && ginStats.nEntries > 0)
    8647          974 :     {
    8648              :         /*
    8649              :          * OK, the stats seem close enough to sane to be trusted.  But we
    8650              :          * still need to scale them by the ratio numPages / nTotalPages to
    8651              :          * account for growth since the last VACUUM.
    8652              :          */
    8653          974 :         double      scale = numPages / ginStats.nTotalPages;
    8654              : 
    8655          974 :         numEntryPages = ceil(ginStats.nEntryPages * scale);
    8656          974 :         numDataPages = ceil(ginStats.nDataPages * scale);
    8657          974 :         numEntries = ceil(ginStats.nEntries * scale);
    8658              :         /* ensure we didn't round up too much */
    8659          974 :         numEntryPages = Min(numEntryPages, numPages - numPendingPages);
    8660          974 :         numDataPages = Min(numDataPages,
    8661              :                            numPages - numPendingPages - numEntryPages);
    8662              :     }
    8663              :     else
    8664              :     {
    8665              :         /*
    8666              :          * We might get here because it's a hypothetical index, or an index
    8667              :          * created pre-9.1 and never vacuumed since upgrading (in which case
    8668              :          * its stats would read as zeroes), or just because it's grown too
    8669              :          * much since the last VACUUM for us to put our faith in scaling.
    8670              :          *
    8671              :          * Invent some plausible internal statistics based on the index page
    8672              :          * count (and clamp that to at least 10 pages, just in case).  We
    8673              :          * estimate that 90% of the index is entry pages, and the rest is data
    8674              :          * pages.  Estimate 100 entries per entry page; this is rather bogus
    8675              :          * since it'll depend on the size of the keys, but it's more robust
    8676              :          * than trying to predict the number of entries per heap tuple.
    8677              :          */
    8678          158 :         numPages = Max(numPages, 10);
    8679          158 :         numEntryPages = floor((numPages - numPendingPages) * 0.90);
    8680          158 :         numDataPages = numPages - numPendingPages - numEntryPages;
    8681          158 :         numEntries = floor(numEntryPages * 100);
    8682              :     }
    8683              : 
    8684              :     /* In an empty index, numEntries could be zero.  Avoid divide-by-zero */
    8685         1132 :     if (numEntries < 1)
    8686            0 :         numEntries = 1;
    8687              : 
    8688              :     /*
    8689              :      * If the index is partial, AND the index predicate with the index-bound
    8690              :      * quals to produce a more accurate idea of the number of rows covered by
    8691              :      * the bound conditions.
    8692              :      */
    8693         1132 :     selectivityQuals = add_predicate_to_index_quals(index, indexQuals);
    8694              : 
    8695              :     /* Estimate the fraction of main-table tuples that will be visited */
    8696         2264 :     *indexSelectivity = clauselist_selectivity(root, selectivityQuals,
    8697         1132 :                                                index->rel->relid,
    8698              :                                                JOIN_INNER,
    8699              :                                                NULL);
    8700              : 
    8701              :     /* fetch estimated page cost for tablespace containing index */
    8702         1132 :     get_tablespace_page_costs(index->reltablespace,
    8703              :                               &spc_random_page_cost,
    8704              :                               NULL);
    8705              : 
    8706              :     /*
    8707              :      * Generic assumption about index correlation: there isn't any.
    8708              :      */
    8709         1132 :     *indexCorrelation = 0.0;
    8710              : 
    8711              :     /*
    8712              :      * Examine quals to estimate number of search entries & partial matches
    8713              :      */
    8714         1132 :     memset(&counts, 0, sizeof(counts));
    8715         1132 :     counts.arrayScans = 1;
    8716         1132 :     matchPossible = true;
    8717              : 
    8718         2369 :     foreach(lc, path->indexclauses)
    8719              :     {
    8720         1237 :         IndexClause *iclause = lfirst_node(IndexClause, lc);
    8721              :         ListCell   *lc2;
    8722              : 
    8723         2468 :         foreach(lc2, iclause->indexquals)
    8724              :         {
    8725         1237 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
    8726         1237 :             Expr       *clause = rinfo->clause;
    8727              : 
    8728         1237 :             if (IsA(clause, OpExpr))
    8729              :             {
    8730         1234 :                 matchPossible = gincost_opexpr(root,
    8731              :                                                index,
    8732         1234 :                                                iclause->indexcol,
    8733              :                                                (OpExpr *) clause,
    8734              :                                                &counts);
    8735         1234 :                 if (!matchPossible)
    8736            6 :                     break;
    8737              :             }
    8738            3 :             else if (IsA(clause, ScalarArrayOpExpr))
    8739              :             {
    8740            3 :                 matchPossible = gincost_scalararrayopexpr(root,
    8741              :                                                           index,
    8742            3 :                                                           iclause->indexcol,
    8743              :                                                           (ScalarArrayOpExpr *) clause,
    8744              :                                                           numEntries,
    8745              :                                                           &counts);
    8746            3 :                 if (!matchPossible)
    8747            0 :                     break;
    8748              :             }
    8749              :             else
    8750              :             {
    8751              :                 /* shouldn't be anything else for a GIN index */
    8752            0 :                 elog(ERROR, "unsupported GIN indexqual type: %d",
    8753              :                      (int) nodeTag(clause));
    8754              :             }
    8755              :         }
    8756              :     }
    8757              : 
    8758              :     /* Fall out if there were any provably-unsatisfiable quals */
    8759         1132 :     if (!matchPossible)
    8760              :     {
    8761            6 :         *indexStartupCost = 0;
    8762            6 :         *indexTotalCost = 0;
    8763            6 :         *indexSelectivity = 0;
    8764            6 :         return;
    8765              :     }
    8766              : 
    8767              :     /*
    8768              :      * If attribute has a full scan and at the same time doesn't have normal
    8769              :      * scan, then we'll have to scan all non-null entries of that attribute.
    8770              :      * Currently, we don't have per-attribute statistics for GIN.  Thus, we
    8771              :      * must assume the whole GIN index has to be scanned in this case.
    8772              :      */
    8773         1126 :     fullIndexScan = false;
    8774         2197 :     for (i = 0; i < index->nkeycolumns; i++)
    8775              :     {
    8776         1240 :         if (counts.attHasFullScan[i] && !counts.attHasNormalScan[i])
    8777              :         {
    8778          169 :             fullIndexScan = true;
    8779          169 :             break;
    8780              :         }
    8781              :     }
    8782              : 
    8783         1126 :     if (fullIndexScan || indexQuals == NIL)
    8784              :     {
    8785              :         /*
    8786              :          * Full index scan will be required.  We treat this as if every key in
    8787              :          * the index had been listed in the query; is that reasonable?
    8788              :          */
    8789          169 :         counts.partialEntries = 0;
    8790          169 :         counts.exactEntries = numEntries;
    8791          169 :         counts.searchEntries = numEntries;
    8792              :     }
    8793              : 
    8794              :     /* Will we have more than one iteration of a nestloop scan? */
    8795         1126 :     outer_scans = loop_count;
    8796              : 
    8797              :     /*
    8798              :      * Compute cost to begin scan, first of all, pay attention to pending
    8799              :      * list.
    8800              :      */
    8801         1126 :     entryPagesFetched = numPendingPages;
    8802              : 
    8803              :     /*
    8804              :      * Estimate number of entry pages read.  We need to do
    8805              :      * counts.searchEntries searches.  Use a power function as it should be,
    8806              :      * but tuples on leaf pages usually is much greater. Here we include all
    8807              :      * searches in entry tree, including search of first entry in partial
    8808              :      * match algorithm
    8809              :      */
    8810         1126 :     entryPagesFetched += ceil(counts.searchEntries * rint(pow(numEntryPages, 0.15)));
    8811              : 
    8812              :     /*
    8813              :      * Add an estimate of entry pages read by partial match algorithm. It's a
    8814              :      * scan over leaf pages in entry tree.  We haven't any useful stats here,
    8815              :      * so estimate it as proportion.  Because counts.partialEntries is really
    8816              :      * pretty bogus (see code above), it's possible that it is more than
    8817              :      * numEntries; clamp the proportion to ensure sanity.
    8818              :      */
    8819         1126 :     partialScale = counts.partialEntries / numEntries;
    8820         1126 :     partialScale = Min(partialScale, 1.0);
    8821              : 
    8822         1126 :     entryPagesFetched += ceil(numEntryPages * partialScale);
    8823              : 
    8824              :     /*
    8825              :      * Partial match algorithm reads all data pages before doing actual scan,
    8826              :      * so it's a startup cost.  Again, we haven't any useful stats here, so
    8827              :      * estimate it as proportion.
    8828              :      */
    8829         1126 :     dataPagesFetched = ceil(numDataPages * partialScale);
    8830              : 
    8831         1126 :     *indexStartupCost = 0;
    8832         1126 :     *indexTotalCost = 0;
    8833              : 
    8834              :     /*
    8835              :      * Add a CPU-cost component to represent the costs of initial entry btree
    8836              :      * descent.  We don't charge any I/O cost for touching upper btree levels,
    8837              :      * since they tend to stay in cache, but we still have to do about log2(N)
    8838              :      * comparisons to descend a btree of N leaf tuples.  We charge one
    8839              :      * cpu_operator_cost per comparison.
    8840              :      *
    8841              :      * If there are ScalarArrayOpExprs, charge this once per SA scan.  The
    8842              :      * ones after the first one are not startup cost so far as the overall
    8843              :      * plan is concerned, so add them only to "total" cost.
    8844              :      */
    8845         1126 :     if (numEntries > 1)          /* avoid computing log(0) */
    8846              :     {
    8847         1126 :         descentCost = ceil(log(numEntries) / log(2.0)) * cpu_operator_cost;
    8848         1126 :         *indexStartupCost += descentCost * counts.searchEntries;
    8849         1126 :         *indexTotalCost += counts.arrayScans * descentCost * counts.searchEntries;
    8850              :     }
    8851              : 
    8852              :     /*
    8853              :      * Add a cpu cost per entry-page fetched. This is not amortized over a
    8854              :      * loop.
    8855              :      */
    8856         1126 :     *indexStartupCost += entryPagesFetched * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8857         1126 :     *indexTotalCost += entryPagesFetched * counts.arrayScans * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8858              : 
    8859              :     /*
    8860              :      * Add a cpu cost per data-page fetched. This is also not amortized over a
    8861              :      * loop. Since those are the data pages from the partial match algorithm,
    8862              :      * charge them as startup cost.
    8863              :      */
    8864         1126 :     *indexStartupCost += DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost * dataPagesFetched;
    8865              : 
    8866              :     /*
    8867              :      * Since we add the startup cost to the total cost later on, remove the
    8868              :      * initial arrayscan from the total.
    8869              :      */
    8870         1126 :     *indexTotalCost += dataPagesFetched * (counts.arrayScans - 1) * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8871              : 
    8872              :     /*
    8873              :      * Calculate cache effects if more than one scan due to nestloops or array
    8874              :      * quals.  The result is pro-rated per nestloop scan, but the array qual
    8875              :      * factor shouldn't be pro-rated (compare genericcostestimate).
    8876              :      */
    8877         1126 :     if (outer_scans > 1 || counts.arrayScans > 1)
    8878              :     {
    8879            3 :         entryPagesFetched *= outer_scans * counts.arrayScans;
    8880            3 :         entryPagesFetched = index_pages_fetched(entryPagesFetched,
    8881              :                                                 (BlockNumber) numEntryPages,
    8882              :                                                 numEntryPages, root);
    8883            3 :         entryPagesFetched /= outer_scans;
    8884            3 :         dataPagesFetched *= outer_scans * counts.arrayScans;
    8885            3 :         dataPagesFetched = index_pages_fetched(dataPagesFetched,
    8886              :                                                (BlockNumber) numDataPages,
    8887              :                                                numDataPages, root);
    8888            3 :         dataPagesFetched /= outer_scans;
    8889              :     }
    8890              : 
    8891              :     /*
    8892              :      * Here we use random page cost because logically-close pages could be far
    8893              :      * apart on disk.
    8894              :      */
    8895         1126 :     *indexStartupCost += (entryPagesFetched + dataPagesFetched) * spc_random_page_cost;
    8896              : 
    8897              :     /*
    8898              :      * Now compute the number of data pages fetched during the scan.
    8899              :      *
    8900              :      * We assume every entry to have the same number of items, and that there
    8901              :      * is no overlap between them. (XXX: tsvector and array opclasses collect
    8902              :      * statistics on the frequency of individual keys; it would be nice to use
    8903              :      * those here.)
    8904              :      */
    8905         1126 :     dataPagesFetched = ceil(numDataPages * counts.exactEntries / numEntries);
    8906              : 
    8907              :     /*
    8908              :      * If there is a lot of overlap among the entries, in particular if one of
    8909              :      * the entries is very frequent, the above calculation can grossly
    8910              :      * under-estimate.  As a simple cross-check, calculate a lower bound based
    8911              :      * on the overall selectivity of the quals.  At a minimum, we must read
    8912              :      * one item pointer for each matching entry.
    8913              :      *
    8914              :      * The width of each item pointer varies, based on the level of
    8915              :      * compression.  We don't have statistics on that, but an average of
    8916              :      * around 3 bytes per item is fairly typical.
    8917              :      */
    8918         1126 :     dataPagesFetchedBySel = ceil(*indexSelectivity *
    8919         1126 :                                  (numTuples / (BLCKSZ / 3)));
    8920         1126 :     if (dataPagesFetchedBySel > dataPagesFetched)
    8921          933 :         dataPagesFetched = dataPagesFetchedBySel;
    8922              : 
    8923              :     /* Add one page cpu-cost to the startup cost */
    8924         1126 :     *indexStartupCost += DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost * counts.searchEntries;
    8925              : 
    8926              :     /*
    8927              :      * Add once again a CPU-cost for those data pages, before amortizing for
    8928              :      * cache.
    8929              :      */
    8930         1126 :     *indexTotalCost += dataPagesFetched * counts.arrayScans * DEFAULT_PAGE_CPU_MULTIPLIER * cpu_operator_cost;
    8931              : 
    8932              :     /* Account for cache effects, the same as above */
    8933         1126 :     if (outer_scans > 1 || counts.arrayScans > 1)
    8934              :     {
    8935            3 :         dataPagesFetched *= outer_scans * counts.arrayScans;
    8936            3 :         dataPagesFetched = index_pages_fetched(dataPagesFetched,
    8937              :                                                (BlockNumber) numDataPages,
    8938              :                                                numDataPages, root);
    8939            3 :         dataPagesFetched /= outer_scans;
    8940              :     }
    8941              : 
    8942              :     /* And apply random_page_cost as the cost per page */
    8943         1126 :     *indexTotalCost += *indexStartupCost +
    8944         1126 :         dataPagesFetched * spc_random_page_cost;
    8945              : 
    8946              :     /*
    8947              :      * Add on index qual eval costs, much as in genericcostestimate. We charge
    8948              :      * cpu but we can disregard indexorderbys, since GIN doesn't support
    8949              :      * those.
    8950              :      */
    8951         1126 :     qual_arg_cost = index_other_operands_eval_cost(root, indexQuals);
    8952         1126 :     qual_op_cost = cpu_operator_cost * list_length(indexQuals);
    8953              : 
    8954         1126 :     *indexStartupCost += qual_arg_cost;
    8955         1126 :     *indexTotalCost += qual_arg_cost;
    8956              : 
    8957              :     /*
    8958              :      * Add a cpu cost per search entry, corresponding to the actual visited
    8959              :      * entries.
    8960              :      */
    8961         1126 :     *indexTotalCost += (counts.searchEntries * counts.arrayScans) * (qual_op_cost);
    8962              :     /* Now add a cpu cost per tuple in the posting lists / trees */
    8963         1126 :     *indexTotalCost += (numTuples * *indexSelectivity) * (cpu_index_tuple_cost);
    8964         1126 :     *indexPages = dataPagesFetched;
    8965              : }
    8966              : 
    8967              : /*
    8968              :  * BRIN has search behavior completely different from other index types
    8969              :  */
    8970              : void
    8971         5365 : brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    8972              :                  Cost *indexStartupCost, Cost *indexTotalCost,
    8973              :                  Selectivity *indexSelectivity, double *indexCorrelation,
    8974              :                  double *indexPages)
    8975              : {
    8976         5365 :     IndexOptInfo *index = path->indexinfo;
    8977         5365 :     List       *indexQuals = get_quals_from_indexclauses(path->indexclauses);
    8978         5365 :     double      numPages = index->pages;
    8979         5365 :     RelOptInfo *baserel = index->rel;
    8980         5365 :     RangeTblEntry *rte = planner_rt_fetch(baserel->relid, root);
    8981              :     Cost        spc_seq_page_cost;
    8982              :     Cost        spc_random_page_cost;
    8983              :     double      qual_arg_cost;
    8984              :     double      qualSelectivity;
    8985              :     BrinStatsData statsData;
    8986              :     double      indexRanges;
    8987              :     double      minimalRanges;
    8988              :     double      estimatedRanges;
    8989              :     double      selec;
    8990              :     Relation    indexRel;
    8991              :     ListCell   *l;
    8992              :     VariableStatData vardata;
    8993              : 
    8994              :     Assert(rte->rtekind == RTE_RELATION);
    8995              : 
    8996              :     /* fetch estimated page cost for the tablespace containing the index */
    8997         5365 :     get_tablespace_page_costs(index->reltablespace,
    8998              :                               &spc_random_page_cost,
    8999              :                               &spc_seq_page_cost);
    9000              : 
    9001              :     /*
    9002              :      * Obtain some data from the index itself, if possible.  Otherwise invent
    9003              :      * some plausible internal statistics based on the relation page count.
    9004              :      */
    9005         5365 :     if (!index->hypothetical)
    9006              :     {
    9007              :         /*
    9008              :          * A lock should have already been obtained on the index in plancat.c.
    9009              :          */
    9010         5365 :         indexRel = index_open(index->indexoid, NoLock);
    9011         5365 :         brinGetStats(indexRel, &statsData);
    9012         5365 :         index_close(indexRel, NoLock);
    9013              : 
    9014              :         /* work out the actual number of ranges in the index */
    9015         5365 :         indexRanges = Max(ceil((double) baserel->pages /
    9016              :                                statsData.pagesPerRange), 1.0);
    9017              :     }
    9018              :     else
    9019              :     {
    9020              :         /*
    9021              :          * Assume default number of pages per range, and estimate the number
    9022              :          * of ranges based on that.
    9023              :          */
    9024            0 :         indexRanges = Max(ceil((double) baserel->pages /
    9025              :                                BRIN_DEFAULT_PAGES_PER_RANGE), 1.0);
    9026              : 
    9027            0 :         statsData.pagesPerRange = BRIN_DEFAULT_PAGES_PER_RANGE;
    9028            0 :         statsData.revmapNumPages = (indexRanges / REVMAP_PAGE_MAXITEMS) + 1;
    9029              :     }
    9030              : 
    9031              :     /*
    9032              :      * Compute index correlation
    9033              :      *
    9034              :      * Because we can use all index quals equally when scanning, we can use
    9035              :      * the largest correlation (in absolute value) among columns used by the
    9036              :      * query.  Start at zero, the worst possible case.  If we cannot find any
    9037              :      * correlation statistics, we will keep it as 0.
    9038              :      */
    9039         5365 :     *indexCorrelation = 0;
    9040              : 
    9041        10731 :     foreach(l, path->indexclauses)
    9042              :     {
    9043         5366 :         IndexClause *iclause = lfirst_node(IndexClause, l);
    9044         5366 :         AttrNumber  attnum = index->indexkeys[iclause->indexcol];
    9045              : 
    9046              :         /* attempt to lookup stats in relation for this index column */
    9047         5366 :         if (attnum != 0)
    9048              :         {
    9049              :             /* Simple variable -- look to stats for the underlying table */
    9050         5366 :             if (get_relation_stats_hook &&
    9051            0 :                 (*get_relation_stats_hook) (root, rte, attnum, &vardata))
    9052              :             {
    9053              :                 /*
    9054              :                  * The hook took control of acquiring a stats tuple.  If it
    9055              :                  * did supply a tuple, it'd better have supplied a freefunc.
    9056              :                  */
    9057            0 :                 if (HeapTupleIsValid(vardata.statsTuple) && !vardata.freefunc)
    9058            0 :                     elog(ERROR,
    9059              :                          "no function provided to release variable stats with");
    9060              :             }
    9061              :             else
    9062              :             {
    9063         5366 :                 vardata.statsTuple =
    9064         5366 :                     SearchSysCache3(STATRELATTINH,
    9065              :                                     ObjectIdGetDatum(rte->relid),
    9066              :                                     Int16GetDatum(attnum),
    9067              :                                     BoolGetDatum(false));
    9068         5366 :                 vardata.freefunc = ReleaseSysCache;
    9069              :             }
    9070              :         }
    9071              :         else
    9072              :         {
    9073              :             /*
    9074              :              * Looks like we've found an expression column in the index. Let's
    9075              :              * see if there's any stats for it.
    9076              :              */
    9077              : 
    9078              :             /* get the attnum from the 0-based index. */
    9079            0 :             attnum = iclause->indexcol + 1;
    9080              : 
    9081            0 :             if (get_index_stats_hook &&
    9082            0 :                 (*get_index_stats_hook) (root, index->indexoid, attnum, &vardata))
    9083              :             {
    9084              :                 /*
    9085              :                  * The hook took control of acquiring a stats tuple.  If it
    9086              :                  * did supply a tuple, it'd better have supplied a freefunc.
    9087              :                  */
    9088            0 :                 if (HeapTupleIsValid(vardata.statsTuple) &&
    9089            0 :                     !vardata.freefunc)
    9090            0 :                     elog(ERROR, "no function provided to release variable stats with");
    9091              :             }
    9092              :             else
    9093              :             {
    9094            0 :                 vardata.statsTuple = SearchSysCache3(STATRELATTINH,
    9095              :                                                      ObjectIdGetDatum(index->indexoid),
    9096              :                                                      Int16GetDatum(attnum),
    9097              :                                                      BoolGetDatum(false));
    9098            0 :                 vardata.freefunc = ReleaseSysCache;
    9099              :             }
    9100              :         }
    9101              : 
    9102         5366 :         if (HeapTupleIsValid(vardata.statsTuple))
    9103              :         {
    9104              :             AttStatsSlot sslot;
    9105              : 
    9106           18 :             if (get_attstatsslot(&sslot, vardata.statsTuple,
    9107              :                                  STATISTIC_KIND_CORRELATION, InvalidOid,
    9108              :                                  ATTSTATSSLOT_NUMBERS))
    9109              :             {
    9110           18 :                 double      varCorrelation = 0.0;
    9111              : 
    9112           18 :                 if (sslot.nnumbers > 0)
    9113           18 :                     varCorrelation = fabs(sslot.numbers[0]);
    9114              : 
    9115           18 :                 if (varCorrelation > *indexCorrelation)
    9116           18 :                     *indexCorrelation = varCorrelation;
    9117              : 
    9118           18 :                 free_attstatsslot(&sslot);
    9119              :             }
    9120              :         }
    9121              : 
    9122         5366 :         ReleaseVariableStats(vardata);
    9123              :     }
    9124              : 
    9125         5365 :     qualSelectivity = clauselist_selectivity(root, indexQuals,
    9126         5365 :                                              baserel->relid,
    9127              :                                              JOIN_INNER, NULL);
    9128              : 
    9129              :     /*
    9130              :      * Now calculate the minimum possible ranges we could match with if all of
    9131              :      * the rows were in the perfect order in the table's heap.
    9132              :      */
    9133         5365 :     minimalRanges = ceil(indexRanges * qualSelectivity);
    9134              : 
    9135              :     /*
    9136              :      * Now estimate the number of ranges that we'll touch by using the
    9137              :      * indexCorrelation from the stats. Careful not to divide by zero (note
    9138              :      * we're using the absolute value of the correlation).
    9139              :      */
    9140         5365 :     if (*indexCorrelation < 1.0e-10)
    9141         5347 :         estimatedRanges = indexRanges;
    9142              :     else
    9143           18 :         estimatedRanges = Min(minimalRanges / *indexCorrelation, indexRanges);
    9144              : 
    9145              :     /* we expect to visit this portion of the table */
    9146         5365 :     selec = estimatedRanges / indexRanges;
    9147              : 
    9148         5365 :     CLAMP_PROBABILITY(selec);
    9149              : 
    9150         5365 :     *indexSelectivity = selec;
    9151              : 
    9152              :     /*
    9153              :      * Compute the index qual costs, much as in genericcostestimate, to add to
    9154              :      * the index costs.  We can disregard indexorderbys, since BRIN doesn't
    9155              :      * support those.
    9156              :      */
    9157         5365 :     qual_arg_cost = index_other_operands_eval_cost(root, indexQuals);
    9158              : 
    9159              :     /*
    9160              :      * Compute the startup cost as the cost to read the whole revmap
    9161              :      * sequentially, including the cost to execute the index quals.
    9162              :      */
    9163         5365 :     *indexStartupCost =
    9164         5365 :         spc_seq_page_cost * statsData.revmapNumPages * loop_count;
    9165         5365 :     *indexStartupCost += qual_arg_cost;
    9166              : 
    9167              :     /*
    9168              :      * To read a BRIN index there might be a bit of back and forth over
    9169              :      * regular pages, as revmap might point to them out of sequential order;
    9170              :      * calculate the total cost as reading the whole index in random order.
    9171              :      */
    9172         5365 :     *indexTotalCost = *indexStartupCost +
    9173         5365 :         spc_random_page_cost * (numPages - statsData.revmapNumPages) * loop_count;
    9174              : 
    9175              :     /*
    9176              :      * Charge a small amount per range tuple which we expect to match to. This
    9177              :      * is meant to reflect the costs of manipulating the bitmap. The BRIN scan
    9178              :      * will set a bit for each page in the range when we find a matching
    9179              :      * range, so we must multiply the charge by the number of pages in the
    9180              :      * range.
    9181              :      */
    9182         5365 :     *indexTotalCost += 0.1 * cpu_operator_cost * estimatedRanges *
    9183         5365 :         statsData.pagesPerRange;
    9184              : 
    9185         5365 :     *indexPages = index->pages;
    9186         5365 : }
        

Generated by: LCOV version 2.0-1